kilo-superpowers-compose 0.1.0 → 0.1.2

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,211 @@
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.2.** 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
35
+
36
+ > ⚠ **Two steps required.** Running only step ① (`npm install -g`) does
37
+ > nothing visible — it only installs the CLI binary, not the agent/command
38
+ > files, the skills link, or `kilo.jsonc`. Skipping step ② is the most
39
+ > common mistake.
40
+
41
+ **Step ① — Install the CLI**:
24
42
 
25
43
  ```bash
26
44
  npm install -g kilo-superpowers-compose
45
+ ```
46
+
47
+ Only installs the CLI binary (the `kilo-superpowers-compose` command
48
+ itself); does not touch your config directory.
49
+
50
+ **Step ② — Install into Kilo**:
51
+
52
+ ```bash
27
53
  kilo-superpowers-compose install
28
54
  ```
29
55
 
30
- 安装完成后重启 Kilo,即可在代理选择器(`/agents`)中看到 `compose`,并使用
31
- `/superpowers` 斜杠命令。
56
+ Copies the 3 agent files to `~/.config/kilo/agent/`, the command to
57
+ `~/.config/kilo/commands/`, creates the skills link at
58
+ `~/.kilo/skills/superpowers`, and adds an entry to `kilo.jsonc`'s
59
+ `skills.paths`. **Idempotent**: safe to re-run.
32
60
 
33
- ### 方式 B:Kilo `plugin` 字段(实验性 / 暂缓)
61
+ **Step — Restart Kilo** (fully quit and reopen the CLI; **Reload Window**
62
+ in VS Code).
34
63
 
35
- 理论上可在 `kilo.jsonc` 中加入 `"plugin": ["kilo-superpowers-compose"]` Kilo 在
36
- 启动时加载本包。但 Kilo 的插件钩子接口尚未稳定文档化,且该机制只能注册技能、无法
37
- 放置代理 / 命令文件,因此 **v0.1 暂不支持**。请使用方式 A。详见
38
- [docs/DESIGN.md §10 Q5](docs/DESIGN.md)。
64
+ After this, `compose` appears in `/agents` and `/superpowers` works. One
65
+ install covers both Kilo CLI and the VS Code Kilo Code extension (they
66
+ share `~/.config/kilo/`).
39
67
 
40
- > 提示:Kilo 官方的分发渠道是 **Marketplace**(把代理复制到 `~/.config/kilo/agents/`、
41
- > 技能复制到 `~/.config/kilo/skills/`)。后续版本会提交到 [kilo-marketplace](https://github.com/Kilo-Org/kilo-marketplace)。
68
+ ### Kilo Marketplace (official channel — coming soon)
42
69
 
43
- ## 安装了什么
70
+ The Marketplace lets you install from the Kilo sidebar with no terminal. We're
71
+ preparing a contribution to
72
+ [`Kilo-Org/kilo-marketplace`](https://github.com/Kilo-Org/kilo-marketplace).
73
+ Until then, use the npm install above.
44
74
 
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`)。
75
+ ## What gets installed
54
76
 
55
- ## 更新与卸载
77
+ - **14 skills** under the `superpowers` namespace, vendored verbatim from
78
+ obra/superpowers `v6.1.1` (MIT): `using-superpowers`, `brainstorming`,
79
+ `test-driven-development`, `systematic-debugging`,
80
+ `verification-before-completion`, `writing-plans`, `executing-plans`,
81
+ `subagent-driven-development`, `requesting-code-review`,
82
+ `receiving-code-review`, `using-git-worktrees`,
83
+ `finishing-a-development-branch`, `dispatching-parallel-agents`,
84
+ `writing-skills`.
85
+ - **3 agents**: `compose` (primary orchestrator), `compose-dev` (TDD
86
+ implementer subagent), `compose-review` (two-stage reviewer subagent). None
87
+ pin a `model` — they use your global default model.
88
+ - **1 slash command**: `/superpowers` (routes to `compose`).
56
89
 
57
- ```bash
58
- # 更新(重新运行安装,幂等)
59
- kilo-superpowers-compose update
90
+ ## Update & uninstall
91
+
92
+ > **Update is also two steps.** `npm update -g` upgrades the package
93
+ > itself; the `update` subcommand re-syncs the artifacts to Kilo's config.
94
+ > Running only step ① won't update your agents/commands/skills link.
60
95
 
61
- # 卸载(清单法精确移除本包安装的全部内容,绝不触碰用户自有文件)
62
- kilo-superpowers-compose uninstall
96
+ **Update** (two steps, after a new version is published):
97
+
98
+ ```bash
99
+ npm update -g kilo-superpowers-compose # ① upgrade the package
100
+ kilo-superpowers-compose update # ② re-sync artifacts to Kilo (idempotent)
63
101
  ```
64
102
 
65
- 更新上游包后,建议:
103
+ You can also just re-run `kilo-superpowers-compose update` (without
104
+ `npm update`) — it refreshes artifacts using the current global package
105
+ version, but won't pull a newer version.
106
+
107
+ **Uninstall** (removes everything this package installed, manifest-based;
108
+ never touches your own files):
66
109
 
67
110
  ```bash
68
- npm update -g kilo-superpowers-compose
69
- kilo-superpowers-compose update
111
+ kilo-superpowers-compose uninstall # remove artifacts
112
+ npm uninstall -g kilo-superpowers-compose # remove the CLI itself
70
113
  ```
71
114
 
72
- 卸载会移除:技能链接、3 个代理文件、`superpowers.md` 命令、`kilo.jsonc` 中本包的
73
- `skills.paths` 条目,以及安装清单。你的其他技能 / 代理 / 配置保持原样。
115
+ Uninstall removes: the skills link, the 3 agent files, the
116
+ `superpowers.md` command, this package's `skills.paths` entry in
117
+ `kilo.jsonc`, and the install manifest. Your own skills, agents, and config
118
+ are left untouched.
119
+
120
+ ## Common mistakes
121
+
122
+ **"I ran `npm install -g` but `/agents` doesn't show `compose`."**
123
+ — You only ran step ①. The CLI is installed, but no agent files, skills
124
+ link, or command were created. Run `kilo-superpowers-compose install`.
74
125
 
75
- ## 命令行用法
126
+ **"I changed package code after install; restarting Kilo doesn't pick it up."**
127
+ — `~/.kilo/skills/superpowers` is a junction pointing to the package
128
+ directory, so package upgrades are picked up automatically. But
129
+ agent/command files were copied at install time and don't auto-update. Run
130
+ `kilo-superpowers-compose update`.
131
+
132
+ **"I added `plugin: ['kilo-superpowers-compose']` to `kilo.jsonc`."**
133
+ — Remove it. Current Kilo doesn't load this field; it only slows startup.
134
+ This package installs via the npm CLI — no `plugin` field needed.
135
+
136
+ ## CLI usage
76
137
 
77
138
  ```text
78
139
  kilo-superpowers-compose <command>
79
140
 
80
- 命令:
81
- install 安装技能、代理与斜杠命令(默认)
82
- uninstall 移除本包安装的全部内容(清单法)
83
- update 重新运行安装(幂等)
141
+ Commands:
142
+ install Install skills, agents, and the slash command (default)
143
+ uninstall Remove everything this package installed (manifest-based)
144
+ update Re-run install (idempotent)
84
145
 
85
- 选项:
86
- -v, --version 显示版本号
87
- -h, --help 显示帮助
146
+ Options:
147
+ -v, --version Show version
148
+ -h, --help Show help
88
149
  ```
89
150
 
90
- ### 环境变量
151
+ ### Environment variables
91
152
 
92
- | 变量 | 作用 |
153
+ | Variable | Purpose |
93
154
  |---|---|
94
- | `KILO_HOME=<path>` | 覆盖用户主目录(多用于测试 / 多配置隔离) |
95
- | `KILO_SUPERPOWERS_PREFIX=1` | (保留)为技能名加前缀;v0.1 `superpowers` 命名空间隔离,故暂未启用 |
96
- | `KILO_SUPERPOWERS_DRY_RUN=1` | 只打印将执行的动作,不修改任何文件 |
97
- | `KILO_SUPERPOWERS_VERBOSE=1` | 输出详细日志(到 stderr |
155
+ | `KILO_HOME=<path>` | Override user home (for testing / isolated configs) |
156
+ | `KILO_SUPERPOWERS_PREFIX=1` | (reserved) prefix skill names; v0.1 isolates via the `superpowers` namespace instead |
157
+ | `KILO_SUPERPOWERS_DRY_RUN=1` | Print intended actions without modifying anything |
158
+ | `KILO_SUPERPOWERS_VERBOSE=1` | Verbose logging (to stderr) |
98
159
 
99
- ### 退出码
160
+ ### Exit codes
100
161
 
101
- `0` 成功 · `1` 一般错误 · `2` `kilo.jsonc` 解析失败(已从备份恢复) · `3` 目标目录不可写 · `4` 技能链接创建失败。
162
+ `0` success · `1` generic error · `2` `kilo.jsonc` parse error (restored from
163
+ backup) · `3` target dir not writable · `4` skills link creation failed.
102
164
 
103
- > **关于 `kilo.jsonc` 注释**:安装器只剥离 `//` 行注释;**块注释 `/* */` 不被处理**。
104
- > 若你的 `kilo.jsonc` 含块注释导致解析失败,安装器会从自动备份恢复并以退出码 `2` 退出。
105
- > 写回时会丢失注释(已知取舍)。
165
+ > **`kilo.jsonc` comments**: the installer strips only `//` line comments;
166
+ > **block comments `/* */` are not handled**. If your `kilo.jsonc` has block
167
+ > comments and fails to parse, the installer restores from the auto-backup and
168
+ > exits with code `2`. Writing back loses comments (accepted trade-off).
106
169
 
107
- ## 注意事项
170
+ ## Notes
108
171
 
109
- - **同名代理覆盖**:若你已有一个名为 `compose` 的代理,安装会覆盖它(v0.1 接受此取舍)。
110
- - **技能命名空间**:14 个技能位于 `superpowers/` 命名空间下,不会与你已有的
111
- `~/.kilo/skills/<name>` 技能冲突;仅当你也存在 `superpowers` 目录时才需留意。
112
- - **Windows 链接**:技能目录用 junction 链接(无需管理员权限);极少数失败会自动
113
- 回退为递归复制。
114
- - **不自动 `postinstall`**:安装是显式的,避免在你不知情时修改 `kilo.jsonc`。
172
+ - **Same-name agent**: if you already have an agent named `compose`, installing
173
+ overwrites it (accepted for v0.1).
174
+ - **Skill namespace**: the 14 skills live under `superpowers/`, so they won't
175
+ collide with your own `~/.kilo/skills/<name>` skills — only an existing
176
+ `superpowers` directory would conflict.
177
+ - **Windows links**: skills are linked via a directory junction (no admin
178
+ rights needed); on rare failure it falls back to a recursive copy.
179
+ - **No auto-`postinstall`**: install is explicit, so your `kilo.jsonc` is never
180
+ modified without you running the command.
115
181
 
116
- ## 开发与测试
182
+ ## Development & testing
117
183
 
118
184
  ```bash
119
- node --test # 零依赖自动化测试(安装器纯逻辑 + install/uninstall 往返)
120
- npm pack # 检视发布包内容
185
+ node --test # zero-dependency tests (installer logic + plugin module + install/uninstall round-trip)
186
+ npm pack # inspect the published tarball
121
187
  ```
122
188
 
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 做了同样的事。我们:
189
+ ## Documentation
136
190
 
137
- 1. 将其重新打包以面向 Kilo(Kilo OpenCode 的一个 fork —— 高度重合)。
138
- 2. 底层技能来源换成 [obra/superpowers](https://github.com/obra/superpowers)(MIT)。
139
- 3. 将编排器设计收紧为纯路由角色(不在内联写代码),并配以严格的两阶段评审子代理。
191
+ - [docs/DESIGN.md](docs/DESIGN.md) architecture, naming, layout, decisions, risks
192
+ - [docs/INSTALLER.md](docs/INSTALLER.md) — `bin/` installer spec and source
193
+ - [docs/AGENTS.md](docs/AGENTS.md) — the three agents (frontmatter + prompts)
194
+ - [docs/REFERENCES.md](docs/REFERENCES.md) — all reference links
195
+ - [NOTICE](NOTICE) — upstream obra/superpowers attribution (tag `v6.1.1`, MIT)
140
196
 
141
- ## 许可证
197
+ ## Inspiration
142
198
 
143
- MIT(见 [LICENSE](LICENSE))。内嵌的 14 个技能来自 obra/superpowers(MIT,
144
- © Jesse Vincent),逐字保留;归属见 [NOTICE](NOTICE)
199
+ This project ports/adapts
200
+ [moyu-by/opencode-mimo-compose](https://github.com/moyu-by/opencode-mimo-compose)
201
+ (which did the same for OpenCode). We: re-target it at Kilo (a Kilo is an
202
+ OpenCode fork — high overlap); swap the skill source to
203
+ [obra/superpowers](https://github.com/obra/superpowers) (MIT); and tighten the
204
+ orchestrator into a pure-routing role (it never writes code itself) with a
205
+ strict two-stage review subagent.
145
206
 
146
- ## 更新日志
207
+ ## License
147
208
 
148
- - **v0.1.0** —— 首个可用版本。14 技能(锁 obra/superpowers `v6.1.1`)、3 代理、
149
- `/superpowers` 命令、零依赖 ESM 安装器(清单法卸载、幂等、跨平台 junction)。
150
- Path A 为受支持路径;Path B(`plugin` 字段)暂缓为实验性。
209
+ MIT — see [LICENSE](LICENSE). The 14 vendored skills are from
210
+ obra/superpowers (MIT, © Jesse Vincent), kept verbatim; attribution in
211
+ [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/bin/lib.js CHANGED
@@ -368,6 +368,8 @@ export function runInstall(opts = {}) {
368
368
  console.log(` kilo.jsonc: skills.paths ${added ? '已新增条目' : '已存在(幂等跳过)'}`);
369
369
  console.log('');
370
370
  console.log(' 请重启 Kilo CLI / VS Code 扩展以加载。');
371
+ console.log('');
372
+ console.log(' 💡 To upgrade later: npm update -g kilo-superpowers-compose && kilo-superpowers-compose update');
371
373
  return EXIT.OK;
372
374
  }
373
375
 
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.2",
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;