kilo-superpowers-compose 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,150 +1,163 @@
1
1
  # kilo-superpowers-compose
2
2
 
3
- > 一个 Kilo Code / Kilo CLI 插件,将 [obra/superpowers](https://github.com/obra/superpowers)
4
- > 开发工作流打包为单个可安装的 npm 包,对外暴露一个 `compose` 编排器代理,驱动
5
- > 头脑风暴 → 规划 → 子代理实现 → 两阶段评审 → 合并的完整流程。
3
+ [![npm version](https://img.shields.io/npm/v/kilo-superpowers-compose.svg)](https://www.npmjs.com/package/kilo-superpowers-compose)
4
+ [![license](https://img.shields.io/npm/l/kilo-superpowers-compose.svg)](./LICENSE)
6
5
 
7
- ## 状态
6
+ > A Kilo Code / Kilo CLI plugin that packages the
7
+ > [obra/superpowers](https://github.com/obra/superpowers) development workflow
8
+ > into a single installable package, exposing a **`compose`** orchestrator agent
9
+ > that drives brainstorming → planning → subagent implementation → two-stage
10
+ > review → merge.
8
11
 
9
- **v0.1.0 —— 可用。** 已实现安装器、14 个内嵌技能、3 个代理、`/superpowers` 命令,
10
- 并通过自动化测试与隔离环境往返验证。详见 [更新日志](#更新日志)。
12
+ ## Status
11
13
 
12
- ## 这个项目做什么(一段话)
14
+ **v0.1.1.** Installed via the npm CLI and verified on both **Kilo CLI** and the
15
+ **VS Code Kilo Code** extension (they share the same config, so one install
16
+ covers both).
13
17
 
14
- 它把 14 个久经考验的 Superpowers 技能 + 3 个专门构建的代理打包成一个名为
15
- `kilo-superpowers-compose` npm 包。运行一条安装命令后,本包会把技能链接到
16
- `~/.kilo/skills/`,把代理的 `.md` 文件复制到 `~/.config/kilo/agent/`,把
17
- `/superpowers` 命令复制到 `~/.config/kilo/commands/`,并在 `kilo.jsonc` 中注册技能
18
- 路径。重启 Kilo CLI VS Code 扩展后,用户即可在代理选择器中看到一个 `compose`
19
- 代理,对任意编码任务运行完整的、有纪律的 Superpowers 工作流。
18
+ > **About the `plugin` field:** Kilo's `plugin: ["…"]` field in `kilo.jsonc`
19
+ > does **not** load npm-named plugins in current Kilo — adding it only slows
20
+ > startup. This package ships a plugin module (`plugin/index.js`) for the
21
+ > future, but **do not add it to the `plugin` field**. Use the npm CLI install
22
+ > below. See [docs/DESIGN.md §10 Q5](docs/DESIGN.md#10-open-questions--decisions-pending).
20
23
 
21
- ## 安装
24
+ ## What it is
22
25
 
23
- ### 方式 A:npm + 显式安装(推荐,已验证)
26
+ `kilo-superpowers-compose` bundles 14 battle-tested Superpowers skills + 3
27
+ purpose-built agents + a `/superpowers` slash command into one npm package.
28
+ Run one install command and the skills link into `~/.kilo/skills/`, the agent
29
+ files copy into `~/.config/kilo/agent/`, the command into
30
+ `~/.config/kilo/commands/`, and `kilo.jsonc` gets the skill path registered.
31
+ Restart Kilo and a `compose` agent appears in the agent picker, ready to run
32
+ the full, disciplined Superpowers workflow on any coding task.
33
+
34
+ ## Installation
24
35
 
25
36
  ```bash
26
37
  npm install -g kilo-superpowers-compose
27
38
  kilo-superpowers-compose install
28
39
  ```
29
40
 
30
- 安装完成后重启 Kilo,即可在代理选择器(`/agents`)中看到 `compose`,并使用
31
- `/superpowers` 斜杠命令。
32
-
33
- ### 方式 B:Kilo `plugin` 字段(实验性 / 暂缓)
41
+ Then restart Kilo. You'll see `compose` in `/agents` and `/superpowers` will
42
+ work. One install covers both Kilo CLI and the VS Code Kilo Code extension
43
+ (they share `~/.config/kilo/`).
34
44
 
35
- 理论上可在 `kilo.jsonc` 中加入 `"plugin": ["kilo-superpowers-compose"]` Kilo
36
- 启动时加载本包。但 Kilo 的插件钩子接口尚未稳定文档化,且该机制只能注册技能、无法
37
- 放置代理 / 命令文件,因此 **v0.1 暂不支持**。请使用方式 A。详见
38
- [docs/DESIGN.md §10 Q5](docs/DESIGN.md)。
45
+ ### Kilo Marketplace (official channel coming soon)
39
46
 
40
- > 提示:Kilo 官方的分发渠道是 **Marketplace**(把代理复制到 `~/.config/kilo/agents/`、
41
- > 技能复制到 `~/.config/kilo/skills/`)。后续版本会提交到 [kilo-marketplace](https://github.com/Kilo-Org/kilo-marketplace)。
47
+ The Marketplace lets you install from the Kilo sidebar with no terminal. We're
48
+ preparing a contribution to
49
+ [`Kilo-Org/kilo-marketplace`](https://github.com/Kilo-Org/kilo-marketplace).
50
+ Until then, use the npm install above.
42
51
 
43
- ## 安装了什么
52
+ ## What gets installed
44
53
 
45
- - `superpowers` 技能目录下的 **14 个技能**(来自 obra/superpowers `v6.1.1`,逐字内嵌):
46
- `using-superpowers`、`brainstorming`、`test-driven-development`、`systematic-debugging`、
47
- `verification-before-completion`、`writing-plans`、`executing-plans`、
48
- `subagent-driven-development`、`requesting-code-review`、`receiving-code-review`、
49
- `using-git-worktrees`、`finishing-a-development-branch`、`dispatching-parallel-agents`、
50
- `writing-skills`。
51
- - **3 个代理**:`compose`(主代理 / 编排器)、`compose-dev`(子代理 / 实现者)、
52
- `compose-review`(子代理 / 评审者)。三者均**不锁定 `model`**,沿用你的全局默认模型。
53
- - **1 个斜杠命令**:`/superpowers`(路由到 `compose`)。
54
+ - **14 skills** under the `superpowers` namespace, vendored verbatim from
55
+ obra/superpowers `v6.1.1` (MIT): `using-superpowers`, `brainstorming`,
56
+ `test-driven-development`, `systematic-debugging`,
57
+ `verification-before-completion`, `writing-plans`, `executing-plans`,
58
+ `subagent-driven-development`, `requesting-code-review`,
59
+ `receiving-code-review`, `using-git-worktrees`,
60
+ `finishing-a-development-branch`, `dispatching-parallel-agents`,
61
+ `writing-skills`.
62
+ - **3 agents**: `compose` (primary orchestrator), `compose-dev` (TDD
63
+ implementer subagent), `compose-review` (two-stage reviewer subagent). None
64
+ pin a `model` — they use your global default model.
65
+ - **1 slash command**: `/superpowers` (routes to `compose`).
54
66
 
55
- ## 更新与卸载
67
+ ## Update & uninstall
56
68
 
57
69
  ```bash
58
- # 更新(重新运行安装,幂等)
70
+ # Update (re-runs install, idempotent)
59
71
  kilo-superpowers-compose update
60
72
 
61
- # 卸载(清单法精确移除本包安装的全部内容,绝不触碰用户自有文件)
73
+ # Remove everything this package installed (manifest-based; never touches your own files)
62
74
  kilo-superpowers-compose uninstall
63
75
  ```
64
76
 
65
- 更新上游包后,建议:
77
+ After bumping the upstream package:
66
78
 
67
79
  ```bash
68
80
  npm update -g kilo-superpowers-compose
69
81
  kilo-superpowers-compose update
70
82
  ```
71
83
 
72
- 卸载会移除:技能链接、3 个代理文件、`superpowers.md` 命令、`kilo.jsonc` 中本包的
73
- `skills.paths` 条目,以及安装清单。你的其他技能 / 代理 / 配置保持原样。
84
+ Uninstall removes: the skills link, the 3 agent files, the `superpowers.md`
85
+ command, the package's `skills.paths` entry in `kilo.jsonc`, and the install
86
+ manifest. Your own skills, agents, and config are left untouched.
74
87
 
75
- ## 命令行用法
88
+ ## CLI usage
76
89
 
77
90
  ```text
78
91
  kilo-superpowers-compose <command>
79
92
 
80
- 命令:
81
- install 安装技能、代理与斜杠命令(默认)
82
- uninstall 移除本包安装的全部内容(清单法)
83
- update 重新运行安装(幂等)
93
+ Commands:
94
+ install Install skills, agents, and the slash command (default)
95
+ uninstall Remove everything this package installed (manifest-based)
96
+ update Re-run install (idempotent)
84
97
 
85
- 选项:
86
- -v, --version 显示版本号
87
- -h, --help 显示帮助
98
+ Options:
99
+ -v, --version Show version
100
+ -h, --help Show help
88
101
  ```
89
102
 
90
- ### 环境变量
103
+ ### Environment variables
91
104
 
92
- | 变量 | 作用 |
105
+ | Variable | Purpose |
93
106
  |---|---|
94
- | `KILO_HOME=<path>` | 覆盖用户主目录(多用于测试 / 多配置隔离) |
95
- | `KILO_SUPERPOWERS_PREFIX=1` | (保留)为技能名加前缀;v0.1 `superpowers` 命名空间隔离,故暂未启用 |
96
- | `KILO_SUPERPOWERS_DRY_RUN=1` | 只打印将执行的动作,不修改任何文件 |
97
- | `KILO_SUPERPOWERS_VERBOSE=1` | 输出详细日志(到 stderr |
107
+ | `KILO_HOME=<path>` | Override user home (for testing / isolated configs) |
108
+ | `KILO_SUPERPOWERS_PREFIX=1` | (reserved) prefix skill names; v0.1 isolates via the `superpowers` namespace instead |
109
+ | `KILO_SUPERPOWERS_DRY_RUN=1` | Print intended actions without modifying anything |
110
+ | `KILO_SUPERPOWERS_VERBOSE=1` | Verbose logging (to stderr) |
98
111
 
99
- ### 退出码
112
+ ### Exit codes
100
113
 
101
- `0` 成功 · `1` 一般错误 · `2` `kilo.jsonc` 解析失败(已从备份恢复) · `3` 目标目录不可写 · `4` 技能链接创建失败。
114
+ `0` success · `1` generic error · `2` `kilo.jsonc` parse error (restored from
115
+ backup) · `3` target dir not writable · `4` skills link creation failed.
102
116
 
103
- > **关于 `kilo.jsonc` 注释**:安装器只剥离 `//` 行注释;**块注释 `/* */` 不被处理**。
104
- > 若你的 `kilo.jsonc` 含块注释导致解析失败,安装器会从自动备份恢复并以退出码 `2` 退出。
105
- > 写回时会丢失注释(已知取舍)。
117
+ > **`kilo.jsonc` comments**: the installer strips only `//` line comments;
118
+ > **block comments `/* */` are not handled**. If your `kilo.jsonc` has block
119
+ > comments and fails to parse, the installer restores from the auto-backup and
120
+ > exits with code `2`. Writing back loses comments (accepted trade-off).
106
121
 
107
- ## 注意事项
122
+ ## Notes
108
123
 
109
- - **同名代理覆盖**:若你已有一个名为 `compose` 的代理,安装会覆盖它(v0.1 接受此取舍)。
110
- - **技能命名空间**:14 个技能位于 `superpowers/` 命名空间下,不会与你已有的
111
- `~/.kilo/skills/<name>` 技能冲突;仅当你也存在 `superpowers` 目录时才需留意。
112
- - **Windows 链接**:技能目录用 junction 链接(无需管理员权限);极少数失败会自动
113
- 回退为递归复制。
114
- - **不自动 `postinstall`**:安装是显式的,避免在你不知情时修改 `kilo.jsonc`。
124
+ - **Same-name agent**: if you already have an agent named `compose`, installing
125
+ overwrites it (accepted for v0.1).
126
+ - **Skill namespace**: the 14 skills live under `superpowers/`, so they won't
127
+ collide with your own `~/.kilo/skills/<name>` skills — only an existing
128
+ `superpowers` directory would conflict.
129
+ - **Windows links**: skills are linked via a directory junction (no admin
130
+ rights needed); on rare failure it falls back to a recursive copy.
131
+ - **No auto-`postinstall`**: install is explicit, so your `kilo.jsonc` is never
132
+ modified without you running the command.
115
133
 
116
- ## 开发与测试
134
+ ## Development & testing
117
135
 
118
136
  ```bash
119
- node --test # 零依赖自动化测试(安装器纯逻辑 + install/uninstall 往返)
120
- npm pack # 检视发布包内容
137
+ node --test # zero-dependency tests (installer logic + plugin module + install/uninstall round-trip)
138
+ npm pack # inspect the published tarball
121
139
  ```
122
140
 
123
- ## 文档
124
-
125
- - [docs/DESIGN.md](docs/DESIGN.md) —— 架构、命名、包布局、设计决策、风险
126
- - [docs/INSTALLER.md](docs/INSTALLER.md) —— `bin/` 安装器规格与源码
127
- - [docs/AGENTS.md](docs/AGENTS.md) —— 三个代理的规格(frontmatter + 系统提示词)
128
- - [docs/REFERENCES.md](docs/REFERENCES.md) —— 所有参考链接(上游项目、Kilo 文档等)
129
- - [NOTICE](NOTICE) —— 上游 obra/superpowers 归属(tag `v6.1.1`,MIT)
130
-
131
- ## 灵感来源
132
-
133
- 本项目移植 / 改编自
134
- [moyu-by/opencode-mimo-compose](https://github.com/moyu-by/opencode-mimo-compose),
135
- 后者为 OpenCode 做了同样的事。我们:
141
+ ## Documentation
136
142
 
137
- 1. 将其重新打包以面向 Kilo(Kilo OpenCode 的一个 fork —— 高度重合)。
138
- 2. 底层技能来源换成 [obra/superpowers](https://github.com/obra/superpowers)(MIT)。
139
- 3. 将编排器设计收紧为纯路由角色(不在内联写代码),并配以严格的两阶段评审子代理。
143
+ - [docs/DESIGN.md](docs/DESIGN.md) architecture, naming, layout, decisions, risks
144
+ - [docs/INSTALLER.md](docs/INSTALLER.md) — `bin/` installer spec and source
145
+ - [docs/AGENTS.md](docs/AGENTS.md) — the three agents (frontmatter + prompts)
146
+ - [docs/REFERENCES.md](docs/REFERENCES.md) — all reference links
147
+ - [NOTICE](NOTICE) — upstream obra/superpowers attribution (tag `v6.1.1`, MIT)
140
148
 
141
- ## 许可证
149
+ ## Inspiration
142
150
 
143
- MIT(见 [LICENSE](LICENSE))。内嵌的 14 个技能来自 obra/superpowers(MIT,
144
- © Jesse Vincent),逐字保留;归属见 [NOTICE](NOTICE)
151
+ This project ports/adapts
152
+ [moyu-by/opencode-mimo-compose](https://github.com/moyu-by/opencode-mimo-compose)
153
+ (which did the same for OpenCode). We: re-target it at Kilo (a Kilo is an
154
+ OpenCode fork — high overlap); swap the skill source to
155
+ [obra/superpowers](https://github.com/obra/superpowers) (MIT); and tighten the
156
+ orchestrator into a pure-routing role (it never writes code itself) with a
157
+ strict two-stage review subagent.
145
158
 
146
- ## 更新日志
159
+ ## License
147
160
 
148
- - **v0.1.0** —— 首个可用版本。14 技能(锁 obra/superpowers `v6.1.1`)、3 代理、
149
- `/superpowers` 命令、零依赖 ESM 安装器(清单法卸载、幂等、跨平台 junction)。
150
- Path A 为受支持路径;Path B(`plugin` 字段)暂缓为实验性。
161
+ MIT — see [LICENSE](LICENSE). The 14 vendored skills are from
162
+ obra/superpowers (MIT, © Jesse Vincent), kept verbatim; attribution in
163
+ [NOTICE](NOTICE).
@@ -1,8 +1,5 @@
1
1
  ---
2
- description: |
3
- Implementation subagent for the compose workflow. Loads TDD,
4
- systematic debugging, and verification-before-completion skills.
5
- Receives a single discrete task; executes it; reports back.
2
+ description: "Implementation subagent for the compose workflow. Executes a single discrete task via TDD, systematic debugging, and verification."
6
3
  mode: subagent
7
4
  ---
8
5
 
@@ -1,8 +1,5 @@
1
1
  ---
2
- description: |
3
- Two-stage code review subagent for the compose workflow.
4
- Stage 1: spec compliance. Stage 2: code quality.
5
- Reports findings by severity (critical / important / nit).
2
+ description: "Two-stage code review subagent (spec compliance + code quality) for the compose workflow. Reports findings only; never edits code."
6
3
  mode: subagent
7
4
  ---
8
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kilo-superpowers-compose",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "将 obra/superpowers 工作流打包为 Kilo 插件:一个 compose 编排器代理、/superpowers 斜杠命令与 14 个技能,一条命令安装。",
5
5
  "keywords": [
6
6
  "kilo",
@@ -29,14 +29,25 @@
29
29
  "engines": {
30
30
  "node": ">=18"
31
31
  },
32
+ "main": "plugin/index.js",
33
+ "exports": {
34
+ ".": "./plugin/index.js"
35
+ },
32
36
  "bin": {
33
37
  "kilo-superpowers-compose": "bin/cli.js"
34
38
  },
39
+ "kilo": {
40
+ "type": "plugin"
41
+ },
42
+ "opencode": {
43
+ "type": "plugin"
44
+ },
35
45
  "files": [
36
46
  "bin",
37
47
  "skills",
38
48
  "agents",
39
49
  "commands",
50
+ "plugin",
40
51
  "NOTICE"
41
52
  ],
42
53
  "scripts": {
@@ -0,0 +1,246 @@
1
+ // plugin/index.js
2
+ // kilo-superpowers-compose — Kilo 插件模块(Path B)。
3
+ //
4
+ // 这是 Path A(npm CLI 安装器,见 bin/)之外的另一条安装路径:
5
+ // 在 kilo.jsonc 里写 `"plugin": ["kilo-superpowers-compose"]`,Kilo 启动时
6
+ // 会加载本模块的默认导出(工厂函数),调用其 `config(config)` 钩子,向**运行时**
7
+ // 配置对象直接注入 3 个 agent 与 skills.paths —— agent 从不落盘,仅存活于运行时。
8
+ //
9
+ // 设计参考:moyu-by/opencode-mimo-compose 的 src/index.js(OpenCode 插件机制)。
10
+ // Kilo 是 OpenCode 的 fork,复用同样的 `config` 钩子契约。
11
+ //
12
+ // 硬性约束(与 bin/lib.js 一致):
13
+ // - 零第三方依赖;仅用 node:fs / node:path / node:os / node:url。
14
+ // - 绝不抛异常:**插件崩溃会让 Kilo 启动失败**。所有 fs / 解析操作均包 try/catch。
15
+ // - 跨平台路径一律用 path.join,绝不手拼反斜杠;尊重 KILO_HOME。
16
+ // - skills.paths 幂等判定用规范化路径比较(path.resolve + toLowerCase)。
17
+ //
18
+ // 自动更新原理:
19
+ // - agents:每次 Kilo 启动由 config 钩子重注(永远取包内最新内容)。
20
+ // - skills:config.skills.paths 指向**包内** skills 目录,`npm update -g` 后即时刷新。
21
+ // - /superpowers 命令:无法经 config 钩子注册(Kilo 无对应钩子),故采用
22
+ // "复制到 ~/.config/kilo/commands/ + 版本标记" 的方式;包升级时标记比对触发重同步。
23
+
24
+ import fs from 'node:fs';
25
+ import path from 'node:path';
26
+ import os from 'node:os';
27
+ import { fileURLToPath } from 'node:url';
28
+
29
+ // ─── 路径常量 ──────────────────────────────────────────────────────────
30
+ // 本文件即 plugin/index.js;其上一级为包根。
31
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
32
+ const PKG_ROOT = path.resolve(__dirname, '..');
33
+
34
+ const AGENTS_SRC = path.join(PKG_ROOT, 'agents');
35
+ const SKILLS_SRC = path.join(PKG_ROOT, 'skills');
36
+ const COMMANDS_SRC = path.join(PKG_ROOT, 'commands');
37
+
38
+ // Kilo 配置目录(尊重 KILO_HOME,便于测试与隔离配置)。
39
+ // 惰性求值 —— 读取在调用时进行(而非模块加载时),使测试可用临时 KILO_HOME 隔离,
40
+ // 不触碰用户真实配置目录。
41
+ function defaultConfigDir() {
42
+ const home = (process.env.KILO_HOME || os.homedir()) + '';
43
+ return path.join(home, '.config', 'kilo');
44
+ }
45
+ function defaultMarkerFile() {
46
+ return path.join(defaultConfigDir(), '.kilo-superpowers-compose-plugin');
47
+ }
48
+ function defaultCommandsDstDir() {
49
+ return path.join(defaultConfigDir(), 'commands');
50
+ }
51
+
52
+ // 包版本(仅用于版本标记比对;读失败回退为占位串)。
53
+ const PKG_VERSION = readPkgVersion(PKG_ROOT);
54
+
55
+ function readPkgVersion(root) {
56
+ try {
57
+ return JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).version || '0.0.0';
58
+ } catch (_) {
59
+ return '0.0.0';
60
+ }
61
+ }
62
+
63
+ // ─── 纯函数 / 路径规范化 ───────────────────────────────────────────────
64
+ // 与 bin/lib.js 的 normalizePath 行为一致,便于 skills.paths 去重判定。
65
+ export function normalizePath(p) {
66
+ try {
67
+ return path.resolve(p).toLowerCase();
68
+ } catch (_) {
69
+ return String(p || '').toLowerCase();
70
+ }
71
+ }
72
+
73
+ // skills.paths 是否已包含目标(规范化比较,跨分隔符 / 大小写)。
74
+ export function skillsPathsContains(paths, target) {
75
+ const t = normalizePath(target);
76
+ return Array.isArray(paths) && paths.some((p) => normalizePath(p) === t);
77
+ }
78
+
79
+ // 去除字符串两端的成对引号。
80
+ function stripQuotes(v) {
81
+ if (v.length >= 2) {
82
+ const a = v[0];
83
+ const b = v[v.length - 1];
84
+ if ((a === '"' && b === '"') || (a === "'" && b === "'")) {
85
+ return v.slice(1, -1);
86
+ }
87
+ }
88
+ return v;
89
+ }
90
+
91
+ // ─── Frontmatter 解析 ──────────────────────────────────────────────────
92
+ // 既支持单行 `key: value`(我们的 3 个 agent description 现均为单行),
93
+ // 也防御性地支持 YAML 块标量(`|` 字面量 / `>` 折叠)以防有人改回多行。
94
+ // 不引入第三方 YAML 解析器 —— 只覆盖我们用到的子集。
95
+ export function parseFrontmatter(content) {
96
+ const m = typeof content === 'string'
97
+ ? content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/)
98
+ : null;
99
+ if (!m) return { data: {}, body: typeof content === 'string' ? content : '' };
100
+ const lines = m[1].split(/\r?\n/);
101
+ const data = {};
102
+ let i = 0;
103
+ while (i < lines.length) {
104
+ const line = lines[i];
105
+ const kv = line.match(/^([\w-]+)[ \t]*:[ \t]*(.*)$/);
106
+ if (!kv) {
107
+ i++;
108
+ continue;
109
+ }
110
+ const key = kv[1];
111
+ let val = kv[2];
112
+ // 块标量:|(字面量,保留换行)或 >(折叠为空格)。
113
+ if (/^[|>][+-]?$/.test(val)) {
114
+ const folded = val.startsWith('>');
115
+ const collected = [];
116
+ i++;
117
+ while (i < lines.length && (lines[i] === '' || /^[ \t]/.test(lines[i]))) {
118
+ collected.push(lines[i].replace(/^[ \t]+/, ''));
119
+ i++;
120
+ }
121
+ val = (folded ? collected.join(' ') : collected.join('\n')).trim();
122
+ data[key] = val;
123
+ continue;
124
+ }
125
+ const tv = val.trim();
126
+ if (tv === 'true') data[key] = true;
127
+ else if (tv === 'false') data[key] = false;
128
+ else data[key] = stripQuotes(tv);
129
+ i++;
130
+ }
131
+ return { data, body: m[2] };
132
+ }
133
+
134
+ // ─── Agent 加载 ────────────────────────────────────────────────────────
135
+ // 读取包内 agents/*.md,剥离 frontmatter 取 description / mode 与正文 prompt。
136
+ export function loadAgents(agentsSrc) {
137
+ const dir = agentsSrc || AGENTS_SRC;
138
+ const agents = {};
139
+ try {
140
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md'));
141
+ for (const file of files) {
142
+ try {
143
+ const content = fs.readFileSync(path.join(dir, file), 'utf8');
144
+ const { data, body } = parseFrontmatter(content);
145
+ const name = file.replace(/\.md$/, '');
146
+ agents[name] = {
147
+ description: data.description || name,
148
+ // primary 保持 primary;其余一律按 subagent 处理(防御性默认)。
149
+ mode: data.mode === 'primary' ? 'primary' : 'subagent',
150
+ prompt: body,
151
+ };
152
+ } catch (_) {
153
+ // 单个 agent 解析失败不阻断其余 agent。
154
+ }
155
+ }
156
+ } catch (_) {
157
+ // agents 目录不存在 / 不可读 → 返回空集(不抛)。
158
+ }
159
+ return agents;
160
+ }
161
+
162
+ // ─── 版本标记:同步复制的命令 ──────────────────────────────────────────
163
+ // agents / skills 每次启动自动重注 / 自动刷新;只有复制的 /superpowers 命令
164
+ // 需要版本标记触发重同步。
165
+ export function needsSetup(markerFile) {
166
+ const f = markerFile || defaultMarkerFile();
167
+ try {
168
+ if (!fs.existsSync(f)) return true;
169
+ return fs.readFileSync(f, 'utf8').trim() !== PKG_VERSION;
170
+ } catch (_) {
171
+ return true;
172
+ }
173
+ }
174
+
175
+ // 执行命令同步:把 commands/superpowers.md 复制到 ~/.config/kilo/commands/,并写标记。
176
+ export function runSetup(opts = {}) {
177
+ const commandsDst = opts.commandsDstDir || defaultCommandsDstDir();
178
+ const mf = opts.markerFile || defaultMarkerFile();
179
+ try {
180
+ const srcCmd = path.join(opts.commandsSrc || COMMANDS_SRC, 'superpowers.md');
181
+ if (fs.existsSync(srcCmd)) {
182
+ try {
183
+ fs.mkdirSync(commandsDst, { recursive: true });
184
+ fs.copyFileSync(srcCmd, path.join(commandsDst, 'superpowers.md'));
185
+ } catch (_) {
186
+ // 命令复制失败不应阻断 agent / skills 注入 —— 仅记录为无命令。
187
+ }
188
+ }
189
+ try {
190
+ fs.mkdirSync(path.dirname(mf), { recursive: true });
191
+ fs.writeFileSync(mf, PKG_VERSION, 'utf8');
192
+ } catch (_) {
193
+ // 标记写失败:下次启动会重试,无致命影响。
194
+ }
195
+ } catch (_) {
196
+ // 整体防御:runSetup 任何异常都不外泄。
197
+ }
198
+ }
199
+
200
+ // ─── 插件工厂(Kilo 加载入口,当前休眠)──────────────────────────────
201
+ // 设计目标:Kilo 按 PluginModule 契约({ server: Plugin },见 @kilocode/plugin)
202
+ // import 本模块、调用 server() 工厂、再调用返回的 config() 钩子,向运行时配置
203
+ // 注入 agents/skills/command。
204
+ //
205
+ // 实测结论(2026-07,见 docs/DESIGN.md §10 Q5):当前 Kilo **不会**经
206
+ // `kilo.jsonc` 的 `plugin:["包名"]` 字段加载 npm 命名插件(该字段无效,还会拖慢
207
+ // 启动)。本模块的 config() 钩子契约本身正确(经 glob 加载器实测可注入 agent),
208
+ // 但作为用户安装方式暂不启用 —— 安装走 npm CLI(见 bin/)。本模块保留待 Kilo
209
+ // 正式支持插件加载后即可启用。命名兼容:同时以 server 命名导出(与 mimo 一致)。
210
+ export async function plugin(_input, _options) {
211
+ // 首次安装或包升级时同步命令(失败被 runSetup 内部吞掉)。
212
+ try {
213
+ if (needsSetup()) runSetup();
214
+ } catch (_) {}
215
+
216
+ const agents = loadAgents();
217
+
218
+ return {
219
+ // config 钩子:**副作用式**改写传入的 Kilo 配置对象(不返回新对象)。
220
+ config: async (kiloConfig) => {
221
+ try {
222
+ if (!kiloConfig || typeof kiloConfig !== 'object') return;
223
+ // 1. 注册 agents:config.agent[name] = { prompt, description, mode }。
224
+ if (!kiloConfig.agent) kiloConfig.agent = {};
225
+ for (const [name, agent] of Object.entries(agents)) {
226
+ kiloConfig.agent[name] = {
227
+ prompt: agent.prompt,
228
+ description: agent.description,
229
+ mode: agent.mode,
230
+ };
231
+ }
232
+ // 2. 注册 skills:config.skills.paths 追加包内 skills 目录(规范化去重)。
233
+ if (!kiloConfig.skills) kiloConfig.skills = {};
234
+ if (!Array.isArray(kiloConfig.skills.paths)) kiloConfig.skills.paths = [];
235
+ if (fs.existsSync(SKILLS_SRC) && !skillsPathsContains(kiloConfig.skills.paths, SKILLS_SRC)) {
236
+ kiloConfig.skills.paths.push(SKILLS_SRC);
237
+ }
238
+ } catch (_) {
239
+ // config 钩子内任何异常都不外泄,避免拖垮 Kilo 启动。
240
+ }
241
+ },
242
+ };
243
+ }
244
+
245
+ export { plugin as server };
246
+ export default plugin;