feat: rename skills/skiff to pouch and move ACK state under .pouch
Use ~/.pouch, the pouch CLI, and .pouch.yaml as the SSOT container. Keep the inner skills/ packages, and store ACK project state in .pouch/ack instead of docs/ack.
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
# Skill 来源模型
|
||||
|
||||
## 背景
|
||||
|
||||
pouch 当前使用 `owned` 表示本仓库 `skills/` 中维护的 Skill,同时还支持
|
||||
`registry` 外部仓库和用户配置的 custom source。
|
||||
|
||||
这些名称混合了不同维度:
|
||||
|
||||
- `owned` 表示所有权。
|
||||
- `registry` 表示来源配置存放在哪里。
|
||||
- `external` 表示内容不在当前仓库。
|
||||
- `collection` 表示一个来源中包含多个 Skill。
|
||||
|
||||
它们不能作为同一层级的互斥类型。例如 custom source 既可能来自外部 Git 仓库,
|
||||
也可能是 collection;因此 `custom` 与 `external` 并不互斥。
|
||||
|
||||
本文建议将用户可见的来源注册方式统一为三类:
|
||||
|
||||
- `builtin`:随当前 pouch 仓库提供的 Skill。
|
||||
- `catalog:<name>`:由 pouch 自带目录预先登记的来源。
|
||||
- `custom:<name>`:用户在本机显式配置的命名来源。
|
||||
|
||||
来源注册方式与获取方式、仓库布局相互独立。builtin、catalog 和 custom 中的任意
|
||||
来源都可以包含一个或多个 Skill;除 builtin 外,catalog 和 custom 都可以使用
|
||||
Git 仓库或本地目录。
|
||||
|
||||
## 迁移前模型
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
S[pouch 可发现的 Skills]
|
||||
|
||||
S --> O["owned<br/>~/.pouch/skills/*"]
|
||||
S --> C["custom source<br/>~/.config/pouch/config.yaml"]
|
||||
S --> R["registry<br/>registry.yaml"]
|
||||
|
||||
O --> O1["本仓库维护<br/>随 pouch 一起分发"]
|
||||
|
||||
C --> C1["本地目录<br/>--local PATH"]
|
||||
C --> C2["指定 Git 仓库<br/>repo + skills_path"]
|
||||
|
||||
R --> R1["外部单 Skill 仓库"]
|
||||
R --> R2["外部 Skill Collection"]
|
||||
R1 --> E["~/.local/share/pouch/externals/"]
|
||||
R2 --> E
|
||||
```
|
||||
|
||||
迁移前实现中:
|
||||
|
||||
- `list` 和 `status` 支持 owned、registry 和 custom source。
|
||||
- `resolve_skill_source` 可以解析三种来源并处理同名歧义。
|
||||
- `select` 只组装 owned 和 registry 条目,尚未展示 custom source。
|
||||
- `.pouch.yaml` 默认将未声明来源的 Skill 解释为 `owned`。
|
||||
- custom source 的 `skills_path` 已经可以包含多个 Skill,本质上也是 collection。
|
||||
|
||||
## 现行模型
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Skill Provider]
|
||||
|
||||
A --> B["builtin<br/>仓库内隐式注册"]
|
||||
A --> C["catalog:waza<br/>pouch 预置目录"]
|
||||
A --> D["custom:company<br/>用户本机配置"]
|
||||
|
||||
B --> B1["skills/ack"]
|
||||
B --> B2["skills/pouch"]
|
||||
B --> B3["skills/builder"]
|
||||
|
||||
C --> C1["Git 或本地目录"]
|
||||
C1 --> C2["单 Skill"]
|
||||
C1 --> C3["Collection"]
|
||||
C3 --> C4["waza/think"]
|
||||
C3 --> C5["waza/check"]
|
||||
|
||||
D --> D1["Git 或本地目录"]
|
||||
D1 --> D2["单 Skill"]
|
||||
D1 --> D3["Collection"]
|
||||
D3 --> D4["company/security-review"]
|
||||
D3 --> D5["company/release"]
|
||||
```
|
||||
|
||||
### 来源注册方式
|
||||
|
||||
| 类型 | 含义 | 配置来源 | 用户界面展示 |
|
||||
| --- | --- | --- | --- |
|
||||
| `builtin` | 随当前 pouch 仓库提供 | `skills/` | `builtin` |
|
||||
| `catalog` | pouch 预先登记、所有用户可发现的来源 | `catalog.yaml` | `catalog:<name>` |
|
||||
| `custom` | 用户在本机显式注册的命名来源 | `~/.config/pouch/config.yaml` | `custom:<name>` |
|
||||
|
||||
`builtin` 比 `owned` 更适合作为用户可见名称,因为它表达 Skill 的分发位置和可用
|
||||
方式,而不是仓库的所有权关系。
|
||||
|
||||
`catalog` 比 `registry` 更准确:当前文件只是 pouch 随仓库维护的预置来源目录,
|
||||
并不是远程注册中心,也不是一种 Skill 来源协议。
|
||||
|
||||
### 三个正交维度
|
||||
|
||||
每个 provider 应由三个维度描述:
|
||||
|
||||
```text
|
||||
registration: builtin | catalog | custom
|
||||
transport: bundled | local | git
|
||||
layout: single | collection
|
||||
```
|
||||
|
||||
custom source 示例:
|
||||
|
||||
```text
|
||||
registration: custom
|
||||
name: company
|
||||
transport: local | git
|
||||
layout: single | collection
|
||||
```
|
||||
|
||||
catalog entry 示例:
|
||||
|
||||
```text
|
||||
registration: catalog
|
||||
name: waza
|
||||
transport: local | git
|
||||
layout: single | collection
|
||||
```
|
||||
|
||||
`external` 只适合描述物理位置,可作为 catalog 和部分 custom provider 的统称,
|
||||
不应成为与 builtin、custom 并列的持久化类型。
|
||||
|
||||
## `select` 展示
|
||||
|
||||
`pouch select` 应同时展示 builtin、catalog 和 custom Skill:
|
||||
|
||||
```text
|
||||
[ ] ack builtin
|
||||
[ ] builder builtin
|
||||
[-] company custom source
|
||||
[ ] company/release custom:company
|
||||
[ ] company/security-review custom:company
|
||||
[-] waza catalog source
|
||||
[ ] waza/check catalog:waza
|
||||
[ ] waza/think catalog:waza
|
||||
```
|
||||
|
||||
建议遵循以下规则:
|
||||
|
||||
- builtin Skill 直接显示 Skill 名称。
|
||||
- catalog 和 custom collection 都使用来源名称作为父节点。
|
||||
- catalog 和 custom Skill 都使用 `<source>/<skill>` 作为选择器键。
|
||||
- 单 Skill 来源可以省略父节点,但仍显示注册方式和来源名称。
|
||||
- 不同来源安装后名称相同时,继续拒绝同时选择,避免覆盖同一安装路径。
|
||||
|
||||
## 配置表示
|
||||
|
||||
新写入的 `.pouch.yaml` 使用以下形式:
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
- name: ack
|
||||
source: builtin
|
||||
- name: security-review
|
||||
source: company
|
||||
- name: think
|
||||
source: catalog:waza
|
||||
```
|
||||
|
||||
custom source 在 manifest 中继续保存其逻辑名称,例如 `company`。这样不同机器可以
|
||||
独立配置仓库地址,而项目只依赖稳定的来源名称。
|
||||
|
||||
## 兼容策略
|
||||
|
||||
用户可见术语已经调整,并保留以下读取兼容,避免已有项目立即失效:
|
||||
|
||||
1. 对外文档、CLI 输出和 selector 统一使用 `builtin`、`catalog:<name>` 和
|
||||
`custom:<name>`。
|
||||
2. 新生成的 `.pouch.yaml` 对内置 Skill 写入 `source: builtin`。
|
||||
3. 读取旧 manifest 时继续接受 `source: owned`,并在解析时归一化为 `builtin`。
|
||||
4. CLI 参数在过渡期继续接受 `--source owned`,但帮助和输出只推荐 `builtin`。
|
||||
5. 读取旧 manifest 中的 `source: registry` 和 `registry: <name>`,归一化为
|
||||
`catalog:<name>`。
|
||||
6. 主文件使用 `catalog.yaml`;不存在时兼容读取旧 `registry.yaml`。
|
||||
7. custom source 的逻辑名称和现有 `config.yaml` 结构保持不变。
|
||||
8. 将 `builtin`、`catalog` 和兼容别名 `owned`、`registry` 设为 custom source
|
||||
保留字。
|
||||
9. `select` 同步接入 custom Skill,并让 custom collection 与 catalog collection
|
||||
使用相同的父子展示逻辑。
|
||||
|
||||
## 实现范围
|
||||
|
||||
当前实现覆盖:
|
||||
|
||||
- `pouch/skills.py`:来源解析、归一化和 builtin 命名。
|
||||
- `pouch/project.py`:manifest 默认值、序列化与旧值兼容。
|
||||
- `pouch/sources.py`:来源保留字。
|
||||
- `pouch/catalog.py`:catalog 配置、checkout 与 Skill 发现。
|
||||
- `pouch/cli.py`:`list`、`status`、`add`、`select` 和输出文案。
|
||||
- `pouch/selector.py`:统一 catalog/custom collection 的父子展示。
|
||||
- CLI 与来源解析测试。
|
||||
- 根 README、`pouch/README.md`、`skills/pouch/SKILL.md` 和相关示例。
|
||||
|
||||
## 验证要求
|
||||
|
||||
实施完成后至少覆盖:
|
||||
|
||||
- builtin Skill 可以通过新名称列出、选择、安装和写入 manifest。
|
||||
- 旧的 `source: owned` manifest 仍可同步。
|
||||
- custom local source 和 custom Git source 都出现在 selector 中。
|
||||
- catalog 单 Skill 和 Collection 都保持可选择。
|
||||
- custom 单 Skill 和 Collection 都保持可选择。
|
||||
- 多来源同名 Skill 必须显式指定来源。
|
||||
- 两个选择最终安装为同一个名称时,selector 拒绝冲突。
|
||||
- `list`、`status`、`select` 对同一来源使用一致术语。
|
||||
|
||||
## 设计前提
|
||||
|
||||
迁移前 `registry.yaml` 的真实职责只是维护 pouch 预置的来源目录,而不是提供远程
|
||||
发布、版本解析或可信签名等注册中心能力,因此现已改为 `catalog.yaml`。如果未来
|
||||
实现真正的远程 registry,应单独定义其协议和与 catalog 的同步关系,不复用旧名称。
|
||||
Reference in New Issue
Block a user