From ad32b2546be9e3868e353b0a65933a289295e578 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: Wed, 12 Aug 2026 18:58:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(installer):=20Kiro=20=E6=8A=8A=20335=20KB?= =?UTF-8?q?=20=E5=A1=9E=E8=BF=9B=E6=AF=8F=E4=B8=80=E8=BD=AE=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=20=E2=80=94=E2=80=94=20=E6=94=B9=E4=B8=BA=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E5=BC=8F=EF=BC=88Aider=20=E7=9A=84=E5=8F=8D=E9=9D=A2?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 继 Aider 之后核查 Kiro。这次的错跟 Aider 正好相反:不是不加载,是**全部加载、 每一轮都加载**。 ## 问题 Kiro 官方文档(kiro.dev/docs/steering)明确:`.kiro/steering/` 下的文件默认 `inclusion: always`,"loaded into every Kiro interaction automatically"。 而我们把 20 个 skill 的正文整个装进了 `.kiro/steering/`。实测: 47 个 md 文件 / 342914 字节 ≈ 335 KB —— 每轮对话全量进上下文 这跟我们当初给 Cline / Kilo Code 修的是同一个问题(那次是 182 KB),解法当时 就设计好了,只是没意识到 Kiro 的 steering 也是常驻性质。 ## 改法:照搬 Cline / Kilo 的索引式 - skills 正文改装 `.kiro/skills/`(不被自动加载) - `.kiro/steering/superpowers-zh.md` 只放索引:核心规则 + 20 个 skill 的触发 条件表,带 `inclusion: always` 335 KB -> 4.4 KB,76 倍。 ## 升级路径(这条最要紧) 老用户通常直接重装而不会先卸载。不清旧布局的话新旧两份并存,335 KB 一点没减 —— 那这次修了等于没修。所以安装时先清 `.kiro/steering/` 下与我们 skill 同名的目录, 并打印清理了几个;卸载同样处理(LEGACY_SKILL_DIRS)。 只删同名目录,**用户自己写的 steering 文件不动** —— 已实测。 ## 文档里两个编造的 frontmatter 键 docs/README.kiro.md 写着加载模式是 `alwaysApply: true` 和 `globs: "*.ts"` —— 这两个键 Kiro 文档里**根本不存在**,是 Cursor / Trae 的约定被误写成了 Kiro 的。 Kiro 实际用 inclusion / fileMatchPattern。已按官方文档重写整篇,并补上默认值 就是 always 这一条(这正是 335 KB 的成因)。 ## 回归守卫 verify-release.sh 新增 Kiro 段:索引存在、带 inclusion: always、20 行表、指向 .kiro/skills/,以及两条硬守卫 —— - steering 下只能有 1 个 md - steering 常驻总字节 < 20 KB 外加升级路径断言:旧布局必须被清、用户自己的文件必须保留。 双向验证过:模拟退回旧布局后两条断言都会失败。 verify-release 93 -> 101 pass。 ## 验证 - 全新装:steering 1 个文件 4437 字节,.kiro/skills/ 下 20 个 skill - 从旧布局升级:342971 -> 4494 字节,清理 20 个旧目录,用户文件保留 - 卸载:零残留,用户 steering 文件逐字节保留 - audit.sh 166 pass / 0 warn / 0 fail、verify-release.sh 101 pass / 0 fail ## 范围 installer、docs、README 简繁、verify-release 均为 fork 自有,零上游偏离。 --- README.md | 6 +- README.zh-Hant.md | 6 +- bin/superpowers-zh.js | 98 ++++++++++++++++++++++++++++++++- docs/README.kiro.md | 112 ++++++++++++++++++++++++-------------- scripts/verify-release.sh | 26 ++++++++- 5 files changed, 200 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 90cf1e7..37806ef 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ AI:在开始实现之前,我需要了解几个关键问题: | [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/` | +| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/skills/` | | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | CLI | `npx superpowers-zh` | `.gemini/skills/` | | [Codex CLI](https://github.com/openai/codex) | CLI | `npx superpowers-zh` | `.codex/skills/` | | [Aider](https://aider.chat) | CLI | `npx superpowers-zh` | `.aider/skills/` | @@ -271,7 +271,7 @@ cp -r superpowers-zh/skills /your/project/.claude/skills # Claude Code / Co cp -r superpowers-zh/skills /your/project/.hermes/skills # Hermes Agent cp -r superpowers-zh/skills /your/project/.cursor/skills # Cursor cp -r superpowers-zh/skills /your/project/.codex/skills # Codex CLI -cp -r superpowers-zh/skills /your/project/.kiro/steering # Kiro +cp -r superpowers-zh/skills /your/project/.kiro/skills # Kiro cp -r superpowers-zh/skills /your/project/skills/custom # DeerFlow 2.0 cp -r superpowers-zh/skills /your/project/.trae/rules # Trae cp -r superpowers-zh/skills /your/project/.agents # Antigravity @@ -295,7 +295,7 @@ cp -r superpowers-zh/skills /your/project/.qoder/skills # Qoder(阿里 AI | Claude Code | `CLAUDE.md` | 项目根目录 | | Copilot CLI | `CLAUDE.md` | 与 Claude Code 共用插件格式 | | Hermes Agent | `HERMES.md` 或 `.hermes.md` | 项目根目录,安装时自动生成 | -| Kiro | `.kiro/steering/*.md` | 支持 always/globs/手动三种模式 | +| Kiro | `.kiro/steering/superpowers-zh.md`(索引,`inclusion: always`)+ `.kiro/skills/` | steering 每轮常驻,故只放索引 | | DeerFlow 2.0 | `skills/custom/*/SKILL.md` | 字节跳动开源 SuperAgent,自动发现自定义 skills | | Trae | `.trae/rules/project_rules.md` | 项目级规则 | | Antigravity | `GEMINI.md` 或 `AGENTS.md` | 项目根目录 | diff --git a/README.zh-Hant.md b/README.zh-Hant.md index c76d38e..d5d9edc 100644 --- a/README.zh-Hant.md +++ b/README.zh-Hant.md @@ -137,7 +137,7 @@ AI:在開始實作之前,我需要了解幾個關鍵問題: | [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/` | +| [Kiro](https://kiro.dev) | IDE | `npx superpowers-zh` | `.kiro/skills/` | | [Gemini CLI](https://github.com/google-gemini/gemini-cli) | CLI | `npx superpowers-zh` | `.gemini/skills/` | | [Codex CLI](https://github.com/openai/codex) | CLI | `npx superpowers-zh` | `.codex/skills/` | | [Aider](https://aider.chat) | CLI | `npx superpowers-zh` | `.aider/skills/` | @@ -271,7 +271,7 @@ cp -r superpowers-zh/skills /your/project/.claude/skills # Claude Code / Co cp -r superpowers-zh/skills /your/project/.hermes/skills # Hermes Agent cp -r superpowers-zh/skills /your/project/.cursor/skills # Cursor cp -r superpowers-zh/skills /your/project/.codex/skills # Codex CLI -cp -r superpowers-zh/skills /your/project/.kiro/steering # Kiro +cp -r superpowers-zh/skills /your/project/.kiro/skills # Kiro cp -r superpowers-zh/skills /your/project/skills/custom # DeerFlow 2.0 cp -r superpowers-zh/skills /your/project/.trae/rules # Trae cp -r superpowers-zh/skills /your/project/.agents # Antigravity @@ -295,7 +295,7 @@ cp -r superpowers-zh/skills /your/project/.qoder/skills # Qoder(阿里 AI | Claude Code | `CLAUDE.md` | 專案根目錄 | | Copilot CLI | `CLAUDE.md` | 與 Claude Code 共用外掛格式 | | Hermes Agent | `HERMES.md` 或 `.hermes.md` | 專案根目錄,安裝時自動產生 | -| Kiro | `.kiro/steering/*.md` | 支援 always/globs/手動三種模式 | +| Kiro | `.kiro/steering/superpowers-zh.md`(索引,`inclusion: always`)+ `.kiro/skills/` | steering 每輪常駐,故只放索引 | | DeerFlow 2.0 | `skills/custom/*/SKILL.md` | 位元組跳動開源 SuperAgent,自動發現自訂 skills | | Trae | `.trae/rules/project_rules.md` | 專案級規則 | | Antigravity | `GEMINI.md` 或 `AGENTS.md` | 專案根目錄 | diff --git a/bin/superpowers-zh.js b/bin/superpowers-zh.js index 1eaee0c..8f4d9bd 100755 --- a/bin/superpowers-zh.js +++ b/bin/superpowers-zh.js @@ -59,7 +59,15 @@ const TARGETS = [ // 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' }, + // Kiro 的 steering 与 Cline / Kilo 的 rules 同性质:**每轮常驻**。官方文档 + // (kiro.dev/docs/steering)明确 `.kiro/steering/` 下的文件默认 inclusion: always, + // "loaded into every Kiro interaction automatically"。 + // v1.7.9 及更早把 20 个 skill 整个装进 .kiro/steering/ —— 实测 47 个 md、335 KB, + // 每一轮全量进上下文。改为与 Cline / Kilo 同一套:skills 放 .kiro/skills/(不被 + // 自动加载),只在 steering 里放一份带 inclusion: always 的小索引。 + // 注意 Kiro 的 frontmatter 键是 inclusion / fileMatchPattern,不是 Cursor 系的 + // alwaysApply / globs —— 我们旧文档写错过,见 docs/README.kiro.md。 + { name: 'Kiro', dir: '.kiro/skills', detect: '.kiro' }, { name: 'DeerFlow', dir: 'skills/custom', detect: 'deer_flow' }, { name: 'Trae', dir: '.trae/skills', detect: '.trae' }, // Antigravity 无 global:其全局 skills 加载路径未在 docs 证实(全局规则走 ~/.gemini/GEMINI.md), @@ -229,6 +237,68 @@ ${skillTable} console.log(` ✅ Cline: bootstrap rule -> ${rulePath}`); } +// Kiro:steering 每轮常驻,所以这里只放索引,skill 正文放 .kiro/skills/ 按需读取。 +// frontmatter 用 Kiro 自己的 inclusion: always(不是 Cursor 系的 alwaysApply)。 +function generateKiroSteeringIndex(projectDir) { + const steeringDir = resolve(projectDir, '.kiro', 'steering'); + mkdirSync(steeringDir, { recursive: true }); + + const skillEntries = scanSkillEntries(SKILLS_SRC); + + // 先清掉旧布局:v1.7.9 及更早把 skill 正文装在 .kiro/steering//。 + // 升级的人通常直接重装而不会先卸载,不清的话新旧两份并存,335 KB 的常驻开销 + // 一点没减 —— 这才是本次要修的东西。只删我们自己装过的那些 skill 同名目录。 + const ourSkillNames = new Set(skillEntries.map(s => s.name)); + let legacyRemoved = 0; + for (const entry of readdirSync(steeringDir, { withFileTypes: true })) { + if (entry.isDirectory() && ourSkillNames.has(entry.name)) { + rmSync(resolve(steeringDir, entry.name), { recursive: true, force: true }); + legacyRemoved++; + } + } + if (legacyRemoved > 0) { + console.log(` 🧹 Kiro: 清理旧布局 ${legacyRemoved} 个 skill 目录 <- .kiro/steering/`); + console.log(` (旧版把正文放在这里,而 steering 每轮常驻,会一直进 prompt)`); + } + const skillTable = skillEntries.map(s => `| ${s.name} | ${s.desc} |`).join('\n'); + + const rule = `--- +inclusion: always +--- + +# Superpowers-ZH 中文增强版 + +你已加载 superpowers-zh 技能框架(${skillEntries.length} 个 skills)。 + +## 核心规则 + +1. **收到任务时,先检查是否有匹配的 skill** — 哪怕只有 1% 的可能性也要检查 +2. **设计先于编码** — 收到功能需求时,先用 brainstorming skill 做需求分析 +3. **测试先于实现** — 写代码前先写测试(TDD) +4. **验证先于完成** — 声称完成前必须运行验证命令 + +## 可用 Skills + +Skills 位于 \`.kiro/skills/\` 目录,每个 skill 有独立的 \`SKILL.md\` 文件。 + +| Skill | 触发条件 | +|-------|---------| +${skillTable} + +## 如何使用 + +当任务匹配某个 skill 的触发条件时,用读文件工具打开对应的 +\`.kiro/skills//SKILL.md\`,并严格遵循其流程。 + +**不要**把 skill 正文复制到本文件 —— \`.kiro/steering/\` 里的内容每轮都进 prompt, +按需读取才能把常驻开销控制在这张索引表。 +`; + + const rulePath = resolve(steeringDir, 'superpowers-zh.md'); + writeFileSync(rulePath, rule, 'utf8'); + console.log(` ✅ Kiro: steering 索引 -> ${rulePath}`); +} + // Kilo Code:v7 起官方推荐 .kilo/rules/ + 在 kilo.jsonc 的 instructions 数组里显式登记, // 但那要改用户的 kilo.jsonc(JSONC 带注释,安全合并困难,且属于侵入用户配置)。 // 官方同时明确 `.kilocode/rules/` 向后兼容且无需配置即生效,故走这条:零配置改动。 @@ -796,6 +866,10 @@ function installForTarget(target, baseDir, isGlobal) { generateCodeBuddyBootstrap(baseDir); } + if (target.name === 'Kiro') { + generateKiroSteeringIndex(baseDir); + } + if (target.name === 'Cline') { generateClineBootstrapRule(baseDir); } @@ -820,7 +894,13 @@ const BOOTSTRAP_DELETE = [ '.agents/rules.md', '.clinerules/superpowers-zh.md', '.kilocode/rules/superpowers-zh.md', + '.kiro/steering/superpowers-zh.md', ]; + +// v1.7.9 及更早把 skill 正文直接装进 .kiro/steering//,而 steering 每轮常驻 —— +// 那 335 KB 会一直进 prompt。升级的用户不会重跑旧版卸载,所以这里按老路径也清一遍, +// 否则新旧两份并存,开销问题原样保留。 +const LEGACY_SKILL_DIRS = ['.kiro/steering']; const BOOTSTRAP_CLEAN_SECTION = [ 'CLAUDE.md', 'GEMINI.md', @@ -947,6 +1027,22 @@ function uninstall(isGlobal) { .map(e => e.name) ); + // 旧布局清理:见 LEGACY_SKILL_DIRS 的说明。老用户跑新版卸载也应清干净。 + if (!isGlobal) { + for (const rel of LEGACY_SKILL_DIRS) { + const legacyDir = resolve(baseDir, rel); + if (!existsSync(legacyDir)) continue; + let n = 0; + for (const entry of readdirSync(legacyDir, { withFileTypes: true })) { + if (entry.isDirectory() && srcSkillNames.has(entry.name)) { + rmSync(resolve(legacyDir, entry.name), { recursive: true, force: true }); + n++; + } + } + if (n > 0) console.log(` ✅ 清理旧布局: 移除 ${n} 个 skills <- ${legacyDir}`); + } + } + const pool = isGlobal ? GLOBAL_TARGETS : TARGETS; let totalSkills = 0; for (const target of pool) { diff --git a/docs/README.kiro.md b/docs/README.kiro.md index 9b2f77c..7806359 100644 --- a/docs/README.kiro.md +++ b/docs/README.kiro.md @@ -2,68 +2,100 @@ 在 [Kiro](https://kiro.dev)(Amazon AI IDE)中使用 superpowers-zh 的完整指南。 +## ⚠️ v1.7.9 及更早版本请重新安装 + +旧版把 20 个 skill 的**正文**直接装进了 `.kiro/steering/`。而 [Kiro 官方文档](https://kiro.dev/docs/steering/)明确:`.kiro/steering/` 下的文件默认 `inclusion: always`,会被 "loaded into every Kiro interaction automatically"。 + +实测那个布局是 **47 个 md、335 KB,每一轮对话全量进上下文**。不是不能用,是每轮都在烧 token。 + +v1.7.10 起改成索引式:**4.4 KB**(76 倍差距)。重装即可,安装器会自动清掉旧布局: + +```bash +cd /your/project +npx superpowers-zh@latest --tool kiro +``` + +会看到: + +``` +🧹 Kiro: 清理旧布局 20 个 skill 目录 <- .kiro/steering/ +✅ Kiro: steering 索引 -> .kiro/steering/superpowers-zh.md +``` + +**你自己写的 steering 文件不会被动** —— 只清理与我们 skill 同名的那些目录。 + ## 快速安装 ```bash cd /your/project -npx superpowers-zh +npx superpowers-zh --tool kiro ``` -安装脚本会自动检测 `.kiro/` 目录并将 skills 复制到 `.kiro/steering/`。 +装两样东西: + +| 位置 | 内容 | 是否每轮常驻 | +|---|---|---| +| `.kiro/steering/superpowers-zh.md` | 索引:核心规则 + 20 个 skill 的触发条件表(约 4.4 KB) | **是**(`inclusion: always`) | +| `.kiro/skills//SKILL.md` | skill 正文 | 否,按需读取 | + +## 工作原理 + +Kiro 用 **Steering** 机制管理 AI 行为规则。关键的三件事: + +- **目录**:`.kiro/steering/`(项目级)、`~/.kiro/steering/`(全局) +- **默认行为**:**没写 `inclusion` 的文件默认就是 always** —— 每次交互自动加载 +- **frontmatter 键**(这是 Kiro 自己的,别和 Cursor 系搞混): + + | 键 | 含义 | + |---|---| + | `inclusion: always` | 每次交互都加载(**默认值**) | + | `inclusion: fileMatch` + `fileMatchPattern` | 匹配特定文件时加载 | + | `inclusion: manual` | 仅在聊天里用 `#steering-file-name` 引用时加载 | + | `inclusion: auto` | 按 `description` 与请求匹配时自动加载 | + +> 📌 v1.7.9 及更早的本文档写着加载模式是 `alwaysApply: true` 和 `globs: "*.ts"` —— **这两个键 Kiro 文档里根本不存在**,是 Cursor / Trae 的约定被误写成了 Kiro 的。已更正。 + +### 为什么正文不放 steering 里 + +因为 steering 是常驻开销。这跟我们对 Cline、Kilo Code 的处理是同一个道理:**常驻的位置只放索引,正文按需读取。** + +索引里明确告诉 Kiro:任务匹配某个 skill 时,去读 `.kiro/skills//SKILL.md` 并遵循其流程。 ## 手动安装 ```bash git clone https://github.com/jnMetaCode/superpowers-zh.git -cp -r superpowers-zh/skills/* /your/project/.kiro/steering/ +mkdir -p /your/project/.kiro/skills +cp -r superpowers-zh/skills/* /your/project/.kiro/skills/ ``` -## 工作原理 - -Kiro 使用 **Steering** 机制管理 AI 行为规则: - -- **目录**:`.kiro/steering/` -- **格式**:Markdown + YAML frontmatter -- **加载模式**: - - `alwaysApply: true` — 每次对话自动加载 - - `globs: "*.ts"` — 匹配特定文件时加载 - - 手动引用 — 在聊天中输入 `#steering-file-name` - -### Skills 与 Steering 的对应 - -superpowers-zh 的 SKILL.md 文件格式与 Kiro Steering 文件兼容(都是 Markdown + YAML frontmatter)。安装后,Kiro 会自动识别并加载 skills。 - -### 推荐配置 - -在 `.kiro/steering/` 中创建 `superpowers.md`: - -```markdown ---- -description: 加载 superpowers skills 框架 -alwaysApply: true ---- - -使用 .kiro/steering/ 目录下的 superpowers skills 来指导工作流程。 -优先使用 brainstorming(头脑风暴)开始新任务。 -``` +> 手动复制不会生成 `.kiro/steering/superpowers-zh.md` 索引,Kiro 不会知道这些 skill 的存在,你需要自己写一份索引。建议优先用 `npx superpowers-zh --tool kiro`。 +> +> **不要**把正文直接拷进 `.kiro/steering/` —— 那正是本次修掉的问题。 ## 使用 -在 Kiro 中,你可以: -- 直接提到 skill 名称:「使用头脑风暴来分析这个需求」 -- 手动引用:在聊天中输入 `#brainstorming` -- Skills 会根据任务类型自动激活 +装好重启 Kiro 后: + +- 直接描述任务即可,索引会引导它去匹配 skill:「帮我加一个导出功能」应触发 brainstorming +- 也可以点名:「用 brainstorming 分析这个需求」 +- 手动引用索引本身:在聊天里输入 `#superpowers-zh` + +## 卸载 + +```bash +npx superpowers-zh --uninstall +``` + +会删除 `.kiro/skills/` 下装过的 skill 和 `.kiro/steering/superpowers-zh.md`,并顺带清理旧布局残留。你自己的 steering 文件保留。 ## 更新 ```bash -cd /your/project -npx superpowers-zh +npx superpowers-zh@latest --tool kiro ``` -重新运行安装命令即可更新到最新版本。 - ## 获取帮助 - 提交 Issue:https://github.com/jnMetaCode/superpowers-zh/issues -- Kiro 文档:https://kiro.dev/docs/steering/ +- Kiro Steering 文档:https://kiro.dev/docs/steering/ diff --git a/scripts/verify-release.sh b/scripts/verify-release.sh index 86f5e0c..22978f7 100755 --- a/scripts/verify-release.sh +++ b/scripts/verify-release.sh @@ -28,7 +28,7 @@ bad() { FAIL=$((FAIL+1)); FAILURES+=("$1"); printf ' ❌ %s\n' "$1"; } # 工具别名 -> 期望的 skills 目录(相对项目根) declare -a SPEC=( "claude:.claude/skills" "cursor:.cursor/skills" "codex:.codex/skills" - "kiro:.kiro/steering" "deerflow:skills/custom" "trae:.trae/skills" + "kiro:.kiro/skills" "deerflow:skills/custom" "trae:.trae/skills" "antigravity:.agents/skills" "vscode:.github/superpowers" "openclaw:skills" "windsurf:.windsurf/skills" "gemini:.gemini/skills" "aider:.aider/skills" "opencode:.opencode/skills" "qwen:.qwen/skills" "hermes:.hermes/skills" @@ -153,6 +153,30 @@ rows=$(grep -cE '^\| [a-z][a-z0-9-]+ \|' "$R") grep -q '\.kilocode/skills/' "$R" && ok || bad "Kilo 索引未指向 .kilocode/skills/" cd /; rm -rf "$T" +T=$(mktemp -d); cd "$T"; node "$INS" --tool kiro >/dev/null 2>&1 +R="$T/.kiro/steering/superpowers-zh.md" +[ -f "$R" ] && ok || bad "Kiro steering 索引未生成" +head -2 "$R" | grep -q '^inclusion: always' && ok || bad "Kiro 索引缺 inclusion: always frontmatter" +rows=$(grep -cE '^\| [a-z][a-z0-9-]+ \|' "$R") +[ "$rows" = "$EXPECT_SKILLS" ] && ok || bad "Kiro 索引表 $rows 行,期望 $EXPECT_SKILLS" +grep -q '\.kiro/skills/' "$R" && ok || bad "Kiro 索引未指向 .kiro/skills/" +# 回归守卫:steering 每轮常驻,里面只能有索引这一个文件。v1.7.9 曾把 20 个 skill +# 正文装在这里 —— 47 个 md、335 KB 每轮进 prompt。别再退回去。 +steer_md=$(find "$T/.kiro/steering" -name '*.md' | wc -l | tr -d ' ') +[ "$steer_md" = "1" ] && ok || bad "Kiro steering 下有 $steer_md 个 md(只该有索引 1 个)—— 正文不能放常驻目录" +steer_bytes=$(find "$T/.kiro/steering" -name '*.md' -exec cat {} + | wc -c | tr -d ' ') +[ "$steer_bytes" -lt 20000 ] && ok || bad "Kiro steering 常驻 $steer_bytes 字节,超过 20 KB 阈值" +cd /; rm -rf "$T" + +# 升级路径:旧布局(正文躺在 steering 下)必须被清掉,否则新旧并存等于没修 +T=$(mktemp -d); cd "$T"; mkdir -p .kiro/steering/brainstorming +echo "旧正文" > .kiro/steering/brainstorming/SKILL.md +printf -- '---\ninclusion: always\n---\n我自己的规则\n' > .kiro/steering/my-own.md +node "$INS" --tool kiro >/dev/null 2>&1 +[ -d "$T/.kiro/steering/brainstorming" ] && bad "Kiro 升级未清理旧布局 .kiro/steering//" || ok +[ -f "$T/.kiro/steering/my-own.md" ] && ok || bad "Kiro 升级误删了用户自己的 steering 文件" +cd /; rm -rf "$T" + echo "" echo "─── F. PATH 探测健壮性(issue #48 新代码)───" T=$(mktemp -d); cd "$T"