skill-flow 1.0.2 → 1.0.3
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 +24 -22
- package/README.zh.md +25 -24
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/services/doctor-service.js +1 -1
- package/dist/services/doctor-service.js.map +1 -1
- package/dist/services/skill-flow.js +1 -1
- package/dist/services/skill-flow.js.map +1 -1
- package/dist/services/source-service.js +4 -4
- package/dist/services/source-service.js.map +1 -1
- package/dist/tests/skill-flow.test.js +1427 -0
- package/dist/tests/skill-flow.test.js.map +1 -1
- package/dist/tui/config-app.js +1 -1
- package/dist/tui/config-app.js.map +1 -1
- package/dist/utils/format.js +1 -1
- package/dist/utils/format.js.map +1 -1
- package/package.json +10 -1
- package/.gstack/browse-network.log +0 -1
- package/.gstack/browse.json +0 -7
- package/.gstack/qa-reports/base-branch.txt +0 -1
- package/.gstack/qa-reports/qa-report-skill-flow-cli-2026-03-22.md +0 -159
- package/.gstack/qa-reports/qa-report-skill-manager-2026-03-22.md +0 -60
- package/docs/DESIGN.md +0 -407
- package/docs/PRD/PRD-1.0.0.md +0 -1862
- package/docs/PRD/renew/PRD-0.0.0.md +0 -26
- package/docs/PRD/renew/PRD-0.0.1.md +0 -408
- package/docs/PRD/renew/PRD-0.0.2.md +0 -705
- package/docs/PRD/renew/PRD-0.0.3.md +0 -740
- package/docs/PRD/renew/PRD-0.0.4.md +0 -1494
- package/docs/README.md +0 -242
- package/docs/plan/PLAN_v1.0.0.md +0 -663
- package/docs/plan/PLAN_v1.0.1.md +0 -845
- package/docs/refrences/README.md +0 -9
- package/docs/refrences/agent-skill-paths.md +0 -274
- package/docs/refrences/config-state-reconciliation.md +0 -199
- package/docs/refrences/naming-dedupe-warning-rules.md +0 -482
- package/img/img-1.jpg +0 -0
|
@@ -1,705 +0,0 @@
|
|
|
1
|
-
我又做了一轮核查,结论比你母版里更明确了:
|
|
2
|
-
|
|
3
|
-
第一,**MVP 不应把所有渠道都当成“同一种目录”处理**。Claude Code、OpenCode、Codex、OpenClaw 对 skills 的发现路径与行为并不一致,尤其 OpenClaw 对 realpath 有约束,Codex 明确支持 symlink,OpenCode 会同时扫 `.opencode/skills`、`.claude/skills`、`.agents/skills`,Claude Code 还有个人级、项目级和嵌套发现。产品层必须把“渠道”定义为 **adapter**,而不是一个路径字符串。([Claude][1])
|
|
4
|
-
|
|
5
|
-
第二,**`manifest + lock` 必须是强制设计,不要允许“无状态运行”**。ClawHub 会把安装状态记到 `.clawhub/lock.json`,Vercel 的 `npx skills` 也依赖 lock file 与 `skillFolderHash` 做更新判断;这些现成实践已经说明,skills 管理器一旦涉及多来源、多渠道、多策略分发,没有锁定层就很难保证更新、回滚和恢复安装。([OpenClaw][2])
|
|
6
|
-
|
|
7
|
-
第三,**source 层要从第一天就按插件接口建模**。Git 仓库是 MVP 主路径,但公开生态已经同时存在 ClawHub registry 工作流,以及 `/.well-known/skills/index.json` 这类 URL 发现协议;如果 source 抽象不先立住,后面每加一个来源都要改核心模型。([OpenClaw][2])
|
|
8
|
-
|
|
9
|
-
第四,**技术栈最稳的选择是 TypeScript + Node.js 22 + oclif + Ink**。原因不是“我偏好 JS”,而是这条链路和你要接入的生态最接近:现有 `npx skills`、ClawHub CLI、OpenClaw 周边工作流都天然贴近 Node 侧;而你的 `config` 是树状多选 TUI,Ink 比传统 flag parser 更适合。Node 22 目前仍处在长期支持窗口内;oclif 本身就是面向可扩展 CLI 的框架;Ink 是 React 风格的 CLI UI;Zod 适合做 manifest/lock/schema 校验;simple-git 适合包一层 git 操作;Vitest 则足够快、适合 CLI 工程。([Node.js][3])
|
|
10
|
-
|
|
11
|
-
下面我直接按你上传 PRD 的骨架,给出一版**增强版 PRD v0.2**。
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# skill-flow PRD v0.2
|
|
16
|
-
|
|
17
|
-
## 文档信息
|
|
18
|
-
|
|
19
|
-
* 产品名称:`skill-flow`
|
|
20
|
-
* 启动命令:`skill-flow`
|
|
21
|
-
* MVP 支持平台:macOS
|
|
22
|
-
* 数据根目录:`~/.skillflow/`(以下简称 `SM_HOME`)
|
|
23
|
-
* 产品定位:统一管理多来源 Agent Skills,完成下载、解析、索引、锁定、更新、分发、卸载与诊断。
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## 背景与本轮调研结论
|
|
28
|
-
|
|
29
|
-
当前 Skills 生态在“skill 目录结构”上已经高度收敛:一个 skill 是一个目录,最小单元是 `SKILL.md`,并带 `name`、`description` 等 frontmatter;可选附带 `scripts/`、`references/`、`assets/` 等内容。OpenCode、Codex、Claude Code 都沿用这一模型,OpenCode 甚至明确要求 `name` 与目录名匹配,并给出命名 regex。([Agent Skills][4])
|
|
30
|
-
|
|
31
|
-
但“本地发现路径”并没有统一。Claude Code 支持 `~/.claude/skills` 与项目级 `.claude/skills`,并支持嵌套自动发现;OpenCode 同时支持 `.opencode/skills`、`.claude/skills`、`.agents/skills` 的全局与项目路径,并会从当前目录向上遍历到 git worktree;Codex 以 `$HOME/.agents/skills`、`$REPO_ROOT/.agents/skills` 为正式发现点,并明确支持 symlink;OpenClaw 则区分 bundled、`~/.openclaw/skills`、`<workspace>/skills`,还允许 `skills.load.extraDirs`,但对 realpath 有边界校验。([Claude][1])
|
|
32
|
-
|
|
33
|
-
这意味着 `skill-flow` 的核心不是“文件搬运”,而是:
|
|
34
|
-
|
|
35
|
-
**Source Resolver → Skill Indexer → Channel Projector**
|
|
36
|
-
|
|
37
|
-
也就是:
|
|
38
|
-
从多来源拿到原始内容,解析为 skill leaf,再按不同渠道的规则安全地投影出去。这个定义与 Vercel `npx skills` 的“canonical copy + symlink/copy dispatch”思路是一致的,但你的产品需要更强的 source 分组、两层树状选择、以及更严格的渠道差异化策略。([GitHub][5])
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## 本轮拍板的关键产品决策
|
|
43
|
-
|
|
44
|
-
### 1. MVP 作用域
|
|
45
|
-
|
|
46
|
-
MVP 只支持 **global scope**,不做通用 project scope;唯一例外是 OpenClaw,因为它的官方模型本来就高度依赖 workspace。也就是说:
|
|
47
|
-
|
|
48
|
-
* Claude Code:先支持 `~/.claude/skills`
|
|
49
|
-
* OpenCode:先支持 `~/.config/opencode/skills`
|
|
50
|
-
* Codex:先支持 `~/.agents/skills`
|
|
51
|
-
* 通用:支持 `~/.agents/skills`
|
|
52
|
-
* OpenClaw:支持 `~/.openclaw/skills` 与 `<workspace>/skills`
|
|
53
|
-
|
|
54
|
-
这样可以避开 Codex trusted project config、OpenCode/Codex/Claude 的 repo 向上遍历等复杂度,把第一版做成“个人级 skills 管理器”。([OpenAI Developers][6])
|
|
55
|
-
|
|
56
|
-
### 2. OpenClaw 默认 copy,不走 symlink
|
|
57
|
-
|
|
58
|
-
OpenClaw 渠道默认采用 `copy` 策略,把 skill 真实落到 `<workspace>/skills` 或 `~/.openclaw/skills`。原因是官方文档明确说明其 discovery 仅接受 realpath 落在配置 root 内的 skill root / `SKILL.md`,这会让“从 `SM_HOME` 跨目录 symlink 进 workspace”的方案存在高概率兼容问题。([OpenClaw][7])
|
|
59
|
-
|
|
60
|
-
### 3. Codex 的正式默认渠道是 `~/.agents/skills`
|
|
61
|
-
|
|
62
|
-
基于当前官方文档,Codex 的正式 user-level skills 目录是 `$HOME/.agents/skills`,并且官方明确说明会跟随 symlink 扫描。因此 MVP 不把 `~/.codex/skills` 作为正式 channel 暴露;若用户确有历史目录习惯,只通过 advanced config 自定义 path override。([OpenAI Developers][6])
|
|
63
|
-
|
|
64
|
-
### 4. 必须有 `manifest.json` 与 `lock.json`
|
|
65
|
-
|
|
66
|
-
* `manifest.json` 记录用户意图:sources、命名策略、channel 绑定关系
|
|
67
|
-
* `lock.json` 记录解析结果:source snapshot、skill leaf、deployment 结果
|
|
68
|
-
|
|
69
|
-
不提供“纯扫描、纯临时分发”的无状态模式。([OpenClaw][2])
|
|
70
|
-
|
|
71
|
-
### 5. `uninstall` 与 `config` 分责
|
|
72
|
-
|
|
73
|
-
* `config` 负责“启用/停用 skill 对某个 channel 的投影”
|
|
74
|
-
* `uninstall` 负责“删除 source、索引和相关投影”
|
|
75
|
-
|
|
76
|
-
也就是说,“某个 channel 不想再用这个 skill”不是 uninstall,而是 config 的 disable 行为。
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 产品定义
|
|
81
|
-
|
|
82
|
-
`skill-flow` 是一个面向 Agent Skills 生态的命令行包管理器。它从 Git 仓库、ClawHub、未来的 well-known discovery URL 等来源拉取 skills,统一存入 `SM_HOME/source`,扫描出合法的 skill leaf,建立本地索引与锁定状态,再按用户选择分发到不同的 agent 渠道目录。技能最终以目录形式暴露给目标 agent,满足其对 `SKILL.md` 的发现要求。([Agent Skills][4])
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## 目标、非目标与成功指标
|
|
87
|
-
|
|
88
|
-
### 目标(MVP)
|
|
89
|
-
|
|
90
|
-
1. 支持 Git source 的添加、扫描、更新、卸载。
|
|
91
|
-
2. 支持 ClawHub source 的添加、更新与锁定。
|
|
92
|
-
3. 建立 Source → Skill 的两层索引模型。
|
|
93
|
-
4. 提供树状多选 TUI 完成渠道配置。
|
|
94
|
-
5. 默认分发到 Claude Code / OpenCode / Codex / OpenClaw / `.agents/skills`。
|
|
95
|
-
6. 对每个渠道应用最合适的策略:`symlink` / `copy` / 配置注入。
|
|
96
|
-
7. 提供 `doctor` 检查路径、冲突、损坏链接和安全风险。
|
|
97
|
-
|
|
98
|
-
### 非目标(MVP)
|
|
99
|
-
|
|
100
|
-
1. 不执行 skill 内的脚本。
|
|
101
|
-
2. 不改写 skill 内容。
|
|
102
|
-
3. 不做 GUI。
|
|
103
|
-
4. 不做组织级远程同步。
|
|
104
|
-
5. 不做通用 project-scope 管理。
|
|
105
|
-
|
|
106
|
-
### 成功指标
|
|
107
|
-
|
|
108
|
-
* 首次安装并在 2 个渠道可用的时间小于 3 分钟。
|
|
109
|
-
* `update --all` 后,无需手工修复即可完成大多数 channel 的一致重投影。
|
|
110
|
-
* 任一次安装/更新/卸载都可通过 state 文件与日志回溯。
|
|
111
|
-
* 失败时不留下半配置状态。
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## 领域模型与系统边界
|
|
116
|
-
|
|
117
|
-
### 核心实体
|
|
118
|
-
|
|
119
|
-
**Source**
|
|
120
|
-
一个可更新的上游来源。
|
|
121
|
-
示例:Git 仓库、ClawHub slug、well-known skills URL。
|
|
122
|
-
|
|
123
|
-
**SourceSnapshot**
|
|
124
|
-
某个 source 的本地解析快照。
|
|
125
|
-
Git 用 commit SHA;ClawHub 用 version/tag;well-known 用 index hash / etag。([OpenClaw][2])
|
|
126
|
-
|
|
127
|
-
**SkillLeaf**
|
|
128
|
-
最终可安装的 skill 单元。一个 leaf 必须能映射到一个合法 skill root,即目录内存在 `SKILL.md` 且 `name`、`description` 可解析。([Agent Skills][4])
|
|
129
|
-
|
|
130
|
-
**Channel**
|
|
131
|
-
一个目标 agent 适配器,不只是路径,还包括发现规则、优先级、以及支持的分发策略。
|
|
132
|
-
|
|
133
|
-
**Deployment**
|
|
134
|
-
一次把若干 leaf 投影到某个 channel 的结果。包含 strategy、目标路径、状态、时间戳。
|
|
135
|
-
|
|
136
|
-
### 系统边界
|
|
137
|
-
|
|
138
|
-
`skill-flow` 只负责:
|
|
139
|
-
|
|
140
|
-
* 获取
|
|
141
|
-
* 校验
|
|
142
|
-
* 索引
|
|
143
|
-
* 锁定
|
|
144
|
-
* 分发
|
|
145
|
-
* 更新
|
|
146
|
-
* 卸载
|
|
147
|
-
* 诊断
|
|
148
|
-
|
|
149
|
-
它不负责运行 skill,不负责替代 agent 的 skill loader,也不负责对脚本做沙箱。官方文档已经把第三方 skills 视作潜在不可信输入,因此本工具只做静态保护与分发安全,不做运行时安全承诺。([OpenClaw][7])
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## 核心命令设计
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
skill-flow add <source>
|
|
157
|
-
skill-flow search <query>
|
|
158
|
-
skill-flow list
|
|
159
|
-
skill-flow config
|
|
160
|
-
skill-flow update [--all | <sourceId>]
|
|
161
|
-
skill-flow uninstall [<sourceId>...]
|
|
162
|
-
skill-flow doctor
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### `add`
|
|
166
|
-
|
|
167
|
-
作用:新增一个 source,并生成索引。
|
|
168
|
-
流程:
|
|
169
|
-
|
|
170
|
-
1. 解析 source 类型
|
|
171
|
-
2. 下载到 `SM_HOME/source/<sourceKey>`
|
|
172
|
-
3. 扫描合法 skill leaf
|
|
173
|
-
4. 更新 `manifest.json` / `lock.json`
|
|
174
|
-
5. 在 `SM_HOME/skills` 建立 canonical entries
|
|
175
|
-
|
|
176
|
-
### `search`
|
|
177
|
-
|
|
178
|
-
MVP 搜索来源:
|
|
179
|
-
|
|
180
|
-
* ClawHub:一级支持
|
|
181
|
-
* GitHub:支持 repo lookup 与 repo search
|
|
182
|
-
* P1:well-known URL discovery
|
|
183
|
-
|
|
184
|
-
ClawHub 已经提供 registry/CLI 工作流;well-known discovery 也已有公开文档与 Mintlify 落地,因此 source adapter 需要预留统一接口。([OpenClaw][2])
|
|
185
|
-
|
|
186
|
-
### `config`
|
|
187
|
-
|
|
188
|
-
交互分三屏:
|
|
189
|
-
|
|
190
|
-
**第一屏:选择渠道**
|
|
191
|
-
展示已检测到的渠道与目标路径。
|
|
192
|
-
|
|
193
|
-
**第二屏:选择 Source / Skill 树**
|
|
194
|
-
|
|
195
|
-
* 一级:source root
|
|
196
|
-
* 二级:skill leaf
|
|
197
|
-
* Space:选中
|
|
198
|
-
* Tab:展开/折叠
|
|
199
|
-
* Enter:确认
|
|
200
|
-
* 一级节点三态:未选 / 部分 / 全选
|
|
201
|
-
|
|
202
|
-
**第三屏:应用确认**
|
|
203
|
-
显示:
|
|
204
|
-
|
|
205
|
-
* 目标 channel
|
|
206
|
-
* 选中 leaf 数量
|
|
207
|
-
* 将创建的 symlink 数
|
|
208
|
-
* 将复制的目录数
|
|
209
|
-
* 冲突数
|
|
210
|
-
* 风险提示数
|
|
211
|
-
|
|
212
|
-
### `uninstall`
|
|
213
|
-
|
|
214
|
-
按 source 粒度删除:
|
|
215
|
-
|
|
216
|
-
* `SM_HOME/source/<sourceKey>`
|
|
217
|
-
* `SM_HOME/skills/<sourceKey>`
|
|
218
|
-
* 所有关联 deployments
|
|
219
|
-
* manifest / lock 中相关条目
|
|
220
|
-
|
|
221
|
-
### `doctor`
|
|
222
|
-
|
|
223
|
-
至少检查:
|
|
224
|
-
|
|
225
|
-
* 目标渠道路径是否存在
|
|
226
|
-
* symlink 是否断裂
|
|
227
|
-
* OpenClaw channel 是否存在 root 外 realpath 风险
|
|
228
|
-
* 同名 skill 冲突
|
|
229
|
-
* lock 与实际磁盘是否漂移
|
|
230
|
-
* 当前 source 是否有可更新项
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## Source 模型与获取策略
|
|
235
|
-
|
|
236
|
-
### Source Adapter 列表
|
|
237
|
-
|
|
238
|
-
#### A. Git Adapter(MVP 必做)
|
|
239
|
-
|
|
240
|
-
支持:
|
|
241
|
-
|
|
242
|
-
* `owner/repo`
|
|
243
|
-
* `https://...git`
|
|
244
|
-
* `git@...`
|
|
245
|
-
* 本地 git 路径
|
|
246
|
-
|
|
247
|
-
落地策略:
|
|
248
|
-
|
|
249
|
-
* 原始仓库以完整工作区形式存入 `SM_HOME/source/git/<sourceKey>`
|
|
250
|
-
* 更新优先用本地 `git fetch/pull`
|
|
251
|
-
* 对 GitHub 源可用 REST Trees API 做轻量更新检查或远程结构预览;GitHub 官方也明确 Trees API 用于树层级对象,Contents API 递归获取目录时有 1000 文件上限,超过时应改用 Trees API。([GitHub Docs][8])
|
|
252
|
-
|
|
253
|
-
#### B. ClawHub Adapter(MVP 必做)
|
|
254
|
-
|
|
255
|
-
支持:
|
|
256
|
-
|
|
257
|
-
* `clawhub:<slug>`
|
|
258
|
-
* `clawhub:<slug>@<version>`
|
|
259
|
-
* 搜索后安装
|
|
260
|
-
|
|
261
|
-
推荐交付方式:
|
|
262
|
-
|
|
263
|
-
* MVP 优先 shell-out 调用 `clawhub`
|
|
264
|
-
* 同步吸收 `.clawhub/lock.json` 中的版本信息到本工具 lock
|
|
265
|
-
|
|
266
|
-
理由是 ClawHub 官方已经有 install / update / sync / lockfile 语义,直接复用能更快上线。([OpenClaw][2])
|
|
267
|
-
|
|
268
|
-
#### C. Well-known Skills Adapter(P1 预留)
|
|
269
|
-
|
|
270
|
-
支持:
|
|
271
|
-
|
|
272
|
-
* 任意 URL
|
|
273
|
-
* 自动探测 `/.well-known/skills/index.json`
|
|
274
|
-
* 下载列出的 skill 文件集
|
|
275
|
-
|
|
276
|
-
Mintlify 已公开支持这一协议,因此这不是“未来幻想”,而是很快会变成真实来源类型。([Mintlify][9])
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Skill 解析与索引规则
|
|
281
|
-
|
|
282
|
-
### Skill 判定
|
|
283
|
-
|
|
284
|
-
一个目录被视为合法 skill,当且仅当:
|
|
285
|
-
|
|
286
|
-
1. 存在 `SKILL.md`
|
|
287
|
-
2. frontmatter 可解析
|
|
288
|
-
3. `name` 存在
|
|
289
|
-
4. `description` 存在
|
|
290
|
-
5. 在标准模式下,`name` 与目录名匹配
|
|
291
|
-
|
|
292
|
-
这与 Agent Skills 规范、OpenCode 规则以及 Codex 的技能格式要求一致。([Agent Skills][4])
|
|
293
|
-
|
|
294
|
-
### 解析结果字段
|
|
295
|
-
|
|
296
|
-
每个 leaf 至少保存:
|
|
297
|
-
|
|
298
|
-
* `skillId`
|
|
299
|
-
* `sourceId`
|
|
300
|
-
* `name`
|
|
301
|
-
* `description`
|
|
302
|
-
* `relativeRoot`
|
|
303
|
-
* `hasScripts`
|
|
304
|
-
* `hasReferences`
|
|
305
|
-
* `hasAssets`
|
|
306
|
-
* `contentHash`
|
|
307
|
-
* `riskFlags[]`
|
|
308
|
-
|
|
309
|
-
### 索引结构
|
|
310
|
-
|
|
311
|
-
UI 上统一呈现为两层:
|
|
312
|
-
|
|
313
|
-
* 一级:Source
|
|
314
|
-
* 二级:SkillLeaf
|
|
315
|
-
|
|
316
|
-
磁盘上分三层:
|
|
317
|
-
|
|
318
|
-
* `source/`:原始来源
|
|
319
|
-
* `skills/`:canonical entries
|
|
320
|
-
* `state/`:manifest/lock/history
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## Channel 适配与分发策略
|
|
325
|
-
|
|
326
|
-
### Claude Code
|
|
327
|
-
|
|
328
|
-
默认目标:`~/.claude/skills`。
|
|
329
|
-
策略:**单 skill symlink**。
|
|
330
|
-
|
|
331
|
-
原因:Claude Code 官方支持个人/项目路径和嵌套发现;但保持 `~/.claude/skills` 为真实目录更稳,避免破坏其他共存文件;同时历史上存在 `/skills` 对 symlink 呈现不一致的问题,所以 `doctor` 需要给出 UX 提示,并允许高级模式切换为 copy。([Claude][1])
|
|
332
|
-
|
|
333
|
-
### OpenCode
|
|
334
|
-
|
|
335
|
-
默认目标:`~/.config/opencode/skills`。
|
|
336
|
-
策略:**symlink**。
|
|
337
|
-
|
|
338
|
-
OpenCode 官方同时兼容 `.claude/skills` 与 `.agents/skills`,但为避免“一个 channel 影响另一个 channel”的隐式耦合,MVP 仍把 OpenCode 作为独立目标目录处理。([OpenCode][10])
|
|
339
|
-
|
|
340
|
-
### Codex
|
|
341
|
-
|
|
342
|
-
默认目标:`~/.agents/skills`。
|
|
343
|
-
策略:**symlink**。
|
|
344
|
-
|
|
345
|
-
Codex 官方明确支持 symlink,并允许通过 `~/.codex/config.toml` 中的 `[[skills.config]]` 对具体 skill 路径做禁用;这给后续的“高级禁用策略”留出了空间,但 MVP 不修改 Codex config,只做文件级分发。([OpenAI Developers][6])
|
|
346
|
-
|
|
347
|
-
### OpenClaw
|
|
348
|
-
|
|
349
|
-
默认目标:
|
|
350
|
-
|
|
351
|
-
* 首选:`<workspace>/skills`
|
|
352
|
-
* 备选:`~/.openclaw/skills`
|
|
353
|
-
|
|
354
|
-
默认策略:**copy**。
|
|
355
|
-
|
|
356
|
-
OpenClaw workspace 默认是 `~/.openclaw/workspace`,官方配置项是 `agents.defaults.workspace`;且 skill discovery 要求 realpath 留在 root 内。由于这与中心化 `SM_HOME` + symlink 方案天然冲突,MVP 对 OpenClaw 不做中心化链接分发,直接 copy。([OpenClaw][11])
|
|
357
|
-
|
|
358
|
-
### 通用 `.agents/skills`
|
|
359
|
-
|
|
360
|
-
默认目标:`~/.agents/skills`。
|
|
361
|
-
策略:**symlink**。
|
|
362
|
-
|
|
363
|
-
这个渠道本身就能被 Codex 与 OpenCode 共同消费,因此可作为默认共享投影点。([OpenCode][10])
|
|
364
|
-
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
## 数据存储与状态文件
|
|
368
|
-
|
|
369
|
-
### 目录结构
|
|
370
|
-
|
|
371
|
-
```text
|
|
372
|
-
~/.skillflow/
|
|
373
|
-
source/
|
|
374
|
-
git/
|
|
375
|
-
<sourceKey>/
|
|
376
|
-
clawhub/
|
|
377
|
-
<sourceKey>/
|
|
378
|
-
wellknown/
|
|
379
|
-
<sourceKey>/
|
|
380
|
-
skills/
|
|
381
|
-
<sourceKey>/
|
|
382
|
-
<skillName>/ -> ../../source/...
|
|
383
|
-
state/
|
|
384
|
-
manifest.json
|
|
385
|
-
lock.json
|
|
386
|
-
channels.json
|
|
387
|
-
history.ndjson
|
|
388
|
-
cache/
|
|
389
|
-
tmp/
|
|
390
|
-
logs/
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### `manifest.json`
|
|
394
|
-
|
|
395
|
-
记录用户意图:
|
|
396
|
-
|
|
397
|
-
* sources[]
|
|
398
|
-
* naming policy
|
|
399
|
-
* channel selections
|
|
400
|
-
* per-channel strategy override(advanced only)
|
|
401
|
-
|
|
402
|
-
### `lock.json`
|
|
403
|
-
|
|
404
|
-
记录解析结果:
|
|
405
|
-
|
|
406
|
-
* schemaVersion
|
|
407
|
-
* source snapshots
|
|
408
|
-
* discovered skill leafs
|
|
409
|
-
* deployments
|
|
410
|
-
* content hashes
|
|
411
|
-
* last update times
|
|
412
|
-
|
|
413
|
-
### `channels.json`
|
|
414
|
-
|
|
415
|
-
记录本机探测与用户 override:
|
|
416
|
-
|
|
417
|
-
* channel id
|
|
418
|
-
* detected path
|
|
419
|
-
* path source
|
|
420
|
-
* available strategies
|
|
421
|
-
* health status
|
|
422
|
-
|
|
423
|
-
### `history.ndjson`
|
|
424
|
-
|
|
425
|
-
记录审计事件:
|
|
426
|
-
|
|
427
|
-
* `add`
|
|
428
|
-
* `scan`
|
|
429
|
-
* `config-apply`
|
|
430
|
-
* `update`
|
|
431
|
-
* `uninstall`
|
|
432
|
-
* `doctor-warning`
|
|
433
|
-
|
|
434
|
-
---
|
|
435
|
-
|
|
436
|
-
## 冲突、错误与原子性
|
|
437
|
-
|
|
438
|
-
### 冲突规则
|
|
439
|
-
|
|
440
|
-
1. **同 channel 同名冲突**
|
|
441
|
-
默认阻止,要求用户二选一。
|
|
442
|
-
|
|
443
|
-
2. **目标路径已有非 skill-flow 文件**
|
|
444
|
-
默认不接管,标记 `foreign-existing`。
|
|
445
|
-
|
|
446
|
-
3. **source 内同名 skill**
|
|
447
|
-
扫描时直接判定 source 非法,需要用户手工选择子路径或忽略。
|
|
448
|
-
|
|
449
|
-
### 原子写入
|
|
450
|
-
|
|
451
|
-
* state 文件写入:`tmp -> fsync -> rename`
|
|
452
|
-
* copy 分发:先复制到临时目录,再原子移动
|
|
453
|
-
* symlink 分发:先校验目标,再替换 link
|
|
454
|
-
* 若 apply 过程中失败,不写 lock 的已完成状态
|
|
455
|
-
|
|
456
|
-
---
|
|
457
|
-
|
|
458
|
-
## 安全策略
|
|
459
|
-
|
|
460
|
-
第三方 skills 应被视为不可信输入。Claude Code 与 OpenClaw 官方文档都明确提示需要像安装软件一样审查来源,尤其警惕技能中包含的脚本、外部依赖和秘密注入。([Claude][1])
|
|
461
|
-
|
|
462
|
-
MVP 安全要求:
|
|
463
|
-
|
|
464
|
-
1. **永不执行脚本**
|
|
465
|
-
只扫描,不运行 `scripts/`。
|
|
466
|
-
|
|
467
|
-
2. **静态校验**
|
|
468
|
-
校验 `SKILL.md`、name、description、目录名匹配关系。
|
|
469
|
-
|
|
470
|
-
3. **路径约束**
|
|
471
|
-
校验任何 target path、link target、copy source 的 realpath。
|
|
472
|
-
|
|
473
|
-
4. **风险标记**
|
|
474
|
-
|
|
475
|
-
* `has-scripts`
|
|
476
|
-
* `invalid-frontmatter`
|
|
477
|
-
* `name-dir-mismatch`
|
|
478
|
-
* `external-symlink`
|
|
479
|
-
* `foreign-existing`
|
|
480
|
-
* `openclaw-root-risk`
|
|
481
|
-
|
|
482
|
-
5. **安装确认**
|
|
483
|
-
对非本地来源默认二次确认;`--yes` 为显式跳过。
|
|
484
|
-
|
|
485
|
-
6. **diff 审计**
|
|
486
|
-
`list --diff` 或 `update --diff` 展示变更摘要。
|
|
487
|
-
|
|
488
|
-
---
|
|
489
|
-
|
|
490
|
-
## 技术栈
|
|
491
|
-
|
|
492
|
-
### 推荐主栈
|
|
493
|
-
|
|
494
|
-
**语言与运行时**
|
|
495
|
-
|
|
496
|
-
* TypeScript 5.x
|
|
497
|
-
* Node.js 22 LTS
|
|
498
|
-
* 包管理:pnpm
|
|
499
|
-
|
|
500
|
-
选择理由:Node 22 仍处于长期支持窗口;而 oclif、Ink、simple-git、Vitest 这套 CLI 工具链在 Node 侧最成熟。([Node.js][3])
|
|
501
|
-
|
|
502
|
-
**CLI 框架**
|
|
503
|
-
|
|
504
|
-
* `oclif`
|
|
505
|
-
|
|
506
|
-
理由:`skill-flow` 不是单文件工具,而是带子命令、可扩展、未来可能开放 source/channel 插件接口的 CLI;oclif 官方就是为可扩展 CLI 设计的。([oclif.github.io][12])
|
|
507
|
-
|
|
508
|
-
**TUI 层**
|
|
509
|
-
|
|
510
|
-
* `Ink`
|
|
511
|
-
|
|
512
|
-
理由:`config` 是树状多选 TUI,Ink 提供 React 风格组件模型与 terminal flexbox 布局,明显比传统 prompt 库更适合复杂交互。([GitHub][13])
|
|
513
|
-
|
|
514
|
-
**Schema / 配置校验**
|
|
515
|
-
|
|
516
|
-
* `Zod`
|
|
517
|
-
|
|
518
|
-
理由:manifest、lock、channel config、source adapter response 都是非可信输入,Zod 的 TypeScript-first schema 模式很适合做运行时校验与类型收敛。([Zod][14])
|
|
519
|
-
|
|
520
|
-
**Git 操作**
|
|
521
|
-
|
|
522
|
-
* 首选:系统 `git` 二进制
|
|
523
|
-
* 封装层:`simple-git`
|
|
524
|
-
|
|
525
|
-
理由:Git 是系统真相源;simple-git 适合作为轻量包装层,不重造 git 协议。([npm][15])
|
|
526
|
-
|
|
527
|
-
**YAML / frontmatter 解析**
|
|
528
|
-
|
|
529
|
-
* `yaml` 或等价 YAML parser
|
|
530
|
-
* frontmatter 解析采用轻薄封装,自定义约束逻辑放在应用层
|
|
531
|
-
|
|
532
|
-
理由:skill 格式的关键不是 Markdown 渲染,而是 frontmatter 的强校验。([npm][16])
|
|
533
|
-
|
|
534
|
-
**测试**
|
|
535
|
-
|
|
536
|
-
* `Vitest`:单元与集成测试
|
|
537
|
-
* `tmpdir` 驱动的文件系统测试
|
|
538
|
-
* fixture repos / fixture skills
|
|
539
|
-
|
|
540
|
-
Vitest 适合 Node/TS 项目,速度快,足够覆盖 CLI 与 parser 工程。([Vitest][17])
|
|
541
|
-
|
|
542
|
-
**发布与 CI**
|
|
543
|
-
|
|
544
|
-
* GitHub Actions
|
|
545
|
-
* npm 发布
|
|
546
|
-
* Homebrew Tap(P1)
|
|
547
|
-
|
|
548
|
-
GitHub 官方文档已提供 Node 项目的 build/test 与 package publishing 工作流,因此这条链路成本最低。([GitHub Docs][18])
|
|
549
|
-
|
|
550
|
-
### 工程分层
|
|
551
|
-
|
|
552
|
-
```text
|
|
553
|
-
src/
|
|
554
|
-
commands/ # oclif commands
|
|
555
|
-
tui/ # Ink screens / widgets
|
|
556
|
-
domain/ # Source / Skill / Channel / Deployment models
|
|
557
|
-
adapters/
|
|
558
|
-
source/
|
|
559
|
-
channel/
|
|
560
|
-
services/
|
|
561
|
-
scan/
|
|
562
|
-
install/
|
|
563
|
-
update/
|
|
564
|
-
deploy/
|
|
565
|
-
doctor/
|
|
566
|
-
state/
|
|
567
|
-
manifest/
|
|
568
|
-
lock/
|
|
569
|
-
migration/
|
|
570
|
-
utils/
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### 插件接口
|
|
574
|
-
|
|
575
|
-
先做**内建插件机制**,不做第三方运行时插件安装。
|
|
576
|
-
|
|
577
|
-
```ts
|
|
578
|
-
interface SourceAdapter {
|
|
579
|
-
kind: "git" | "clawhub" | "wellknown";
|
|
580
|
-
probe(input: string): boolean;
|
|
581
|
-
resolve(input: string): Promise<ResolvedSource>;
|
|
582
|
-
fetch(source: ResolvedSource, ctx: FetchContext): Promise<SourceSnapshot>;
|
|
583
|
-
update(snapshot: SourceSnapshot, ctx: UpdateContext): Promise<SourceSnapshot>;
|
|
584
|
-
scan(snapshot: SourceSnapshot): Promise<DiscoveredSkill[]>;
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
```ts
|
|
589
|
-
interface ChannelAdapter {
|
|
590
|
-
kind: "claude" | "opencode" | "codex" | "openclaw" | "agents";
|
|
591
|
-
detect(ctx: DetectContext): Promise<DetectedChannel | null>;
|
|
592
|
-
plan(skills: SkillLeaf[], channel: DetectedChannel): Promise<DeploymentPlan>;
|
|
593
|
-
apply(plan: DeploymentPlan): Promise<DeploymentResult>;
|
|
594
|
-
diagnose(channel: DetectedChannel): Promise<DoctorFinding[]>;
|
|
595
|
-
}
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
---
|
|
599
|
-
|
|
600
|
-
## 测试策略
|
|
601
|
-
|
|
602
|
-
### 单元测试
|
|
603
|
-
|
|
604
|
-
覆盖:
|
|
605
|
-
|
|
606
|
-
* source locator parser
|
|
607
|
-
* frontmatter validator
|
|
608
|
-
* skill scanner
|
|
609
|
-
* naming / conflict rules
|
|
610
|
-
* lock migration
|
|
611
|
-
|
|
612
|
-
### 集成测试
|
|
613
|
-
|
|
614
|
-
用 fixture repo / fixture channel dirs 做黑盒测试:
|
|
615
|
-
|
|
616
|
-
1. add git source
|
|
617
|
-
2. config apply to Claude / OpenCode / Codex
|
|
618
|
-
3. OpenClaw copy deployment
|
|
619
|
-
4. update with changed leaf
|
|
620
|
-
5. uninstall rollback
|
|
621
|
-
6. broken symlink detection
|
|
622
|
-
|
|
623
|
-
### 回归测试
|
|
624
|
-
|
|
625
|
-
重点盯三个高风险点:
|
|
626
|
-
|
|
627
|
-
* OpenClaw realpath
|
|
628
|
-
* Claude symlink UX
|
|
629
|
-
* 同名 skill 冲突恢复
|
|
630
|
-
|
|
631
|
-
---
|
|
632
|
-
|
|
633
|
-
## 里程碑
|
|
634
|
-
|
|
635
|
-
### Iteration 1
|
|
636
|
-
|
|
637
|
-
* 基础目录结构
|
|
638
|
-
* Git source
|
|
639
|
-
* scan / list / lock
|
|
640
|
-
* Zod schema + state migration
|
|
641
|
-
|
|
642
|
-
### Iteration 2
|
|
643
|
-
|
|
644
|
-
* config TUI
|
|
645
|
-
* Claude / OpenCode / Codex / agents 分发
|
|
646
|
-
* symlink deploy + doctor
|
|
647
|
-
|
|
648
|
-
### Iteration 3
|
|
649
|
-
|
|
650
|
-
* OpenClaw copy deploy
|
|
651
|
-
* ClawHub adapter
|
|
652
|
-
* update / uninstall / diff
|
|
653
|
-
|
|
654
|
-
### Iteration 4
|
|
655
|
-
|
|
656
|
-
* search
|
|
657
|
-
* well-known adapter
|
|
658
|
-
* Homebrew 发布
|
|
659
|
-
* advanced config / custom channel path
|
|
660
|
-
|
|
661
|
-
---
|
|
662
|
-
|
|
663
|
-
## 剩余开放问题
|
|
664
|
-
|
|
665
|
-
1. `SM_HOME` 是否允许 `skillflow_HOME` override。
|
|
666
|
-
2. `search` 的 GitHub 模式是否做 repo search,还是 MVP 先只接受 locator。
|
|
667
|
-
3. 是否要在 `config` 里暴露“高级策略切换”,还是完全自动化。
|
|
668
|
-
4. P1 是否支持 project scope。
|
|
669
|
-
|
|
670
|
-
---
|
|
671
|
-
|
|
672
|
-
## 我的最终建议
|
|
673
|
-
|
|
674
|
-
如果你要尽快开工,这一版最值得立刻落地的不是更多竞品调研,而是下面这组最小闭环:
|
|
675
|
-
|
|
676
|
-
**TypeScript + Node 22 + oclif + Ink + Zod + simple-git**
|
|
677
|
-
**先做 Git Source + Claude/OpenCode/Codex/agents symlink + OpenClaw copy + manifest/lock + doctor**
|
|
678
|
-
|
|
679
|
-
这条路线最稳,原因是它同时满足:
|
|
680
|
-
|
|
681
|
-
* 你的两层树状交互诉求
|
|
682
|
-
* 多渠道差异化投影
|
|
683
|
-
* 后续扩展 ClawHub / well-known source
|
|
684
|
-
* 真实可维护的 CLI 工程形态
|
|
685
|
-
|
|
686
|
-
下一步最合适的是把这份 PRD继续压成**工程实施文档**,具体到命令参数 spec、state JSON schema、adapter 接口、错误码与 TUI 组件树。
|
|
687
|
-
|
|
688
|
-
[1]: https://code.claude.com/docs/en/skills?utm_source=chatgpt.com "Extend Claude with skills - Claude Code Docs"
|
|
689
|
-
[2]: https://docs.openclaw.ai/tools/clawhub?utm_source=chatgpt.com "ClawHub - OpenClaw"
|
|
690
|
-
[3]: https://nodejs.org/en/blog/announcements/node-18-eol-support?utm_source=chatgpt.com "Beware of End-of-Life Node.js Versions - Upgrade or Seek ..."
|
|
691
|
-
[4]: https://agentskills.io/specification?utm_source=chatgpt.com "Specification"
|
|
692
|
-
[5]: https://github.com/vercel-labs/skills?utm_source=chatgpt.com "vercel-labs/skills: The open agent skills tool - npx skills"
|
|
693
|
-
[6]: https://developers.openai.com/codex/skills/?utm_source=chatgpt.com "Agent Skills – Codex"
|
|
694
|
-
[7]: https://docs.openclaw.ai/tools/skills?utm_source=chatgpt.com "Skills - OpenClaw"
|
|
695
|
-
[8]: https://docs.github.com/en/rest/git/trees?utm_source=chatgpt.com "REST API endpoints for Git trees"
|
|
696
|
-
[9]: https://www.mintlify.com/docs/ai/skillmd?utm_source=chatgpt.com "skill.md"
|
|
697
|
-
[10]: https://opencode.ai/docs/skills/?utm_source=chatgpt.com "Agent Skills"
|
|
698
|
-
[11]: https://docs.openclaw.ai/gateway/configuration?utm_source=chatgpt.com "Configuration - OpenClaw"
|
|
699
|
-
[12]: https://oclif.github.io/?utm_source=chatgpt.com "oclif: The Open CLI Framework"
|
|
700
|
-
[13]: https://github.com/vadimdemedes/ink?utm_source=chatgpt.com "Ink - React for interactive command-line apps ..."
|
|
701
|
-
[14]: https://zod.dev/?utm_source=chatgpt.com "Zod: Intro"
|
|
702
|
-
[15]: https://www.npmjs.com/package/simple-git?utm_source=chatgpt.com "simple-git"
|
|
703
|
-
[16]: https://www.npmjs.com/package/yaml?utm_source=chatgpt.com "yaml"
|
|
704
|
-
[17]: https://vitest.dev/?utm_source=chatgpt.com "Vitest | Next Generation testing framework"
|
|
705
|
-
[18]: https://docs.github.com/actions/guides/building-and-testing-nodejs?utm_source=chatgpt.com "Building and testing Node.js"
|