Files
sgg-sgg-ai-skill-manage-win…/docs/superpowers/specs/2026-05-13-ai-skill-manager-design.md

462 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Skill Manager Windows 设计规格
## 背景
本项目是一个基于 Wails 的 Windows 桌面应用,用于从 Gitea 组织仓库中发现、下载、更新和安装 AI skill。首版面向 Codex 和 Claude 两个目标应用,后续可以扩展到其他应用。
项目约束:
- 不使用 git worktree。
- 一个 Gitea 仓库对应一个 skill。
- 只有仓库根目录存在 `SKILL.md` 时,才认为该仓库是有效 skill。
- 本地只保留一份 skill 仓库,安装到目标应用时使用 Windows 目录 Junction不复制完整目录。
## 首版范围
首版包含三类页面:
1. 配置页
2. 远程市场页
3. 本地管理页
首版支持:
- 配置 Gitea `baseURL`、认证方式、账号密码或 Token、组织名。
- 默认使用账号密码认证,同时支持 Token 认证。
- 从指定 Gitea 组织读取仓库列表。
- 只展示根目录存在 `SKILL.md` 的仓库。
- 将 skill 仓库 clone 到本地应用数据目录。
- 对已下载仓库执行手动更新和自动更新。
- 将本地 skill 通过 Junction 安装到 Codex 和 Claude。
- 从 Codex 和 Claude 卸载本软件创建的 Junction。
- 删除本地 skill 仓库。
- 使用 VS Code 打开 skill 目录。
- 使用资源管理器打开 skill 目录。
首版不包含:
- 多 Gitea 实例或多组织同时管理。
- GitHub、GitLab 或其他代码托管源。
- skill 版本选择、回滚和发布管理。
- 自动解决本地未提交改动。
- 批量安装、批量卸载和批量删除。
## 路径约定
应用数据目录:
```text
%APPDATA%\sgg-ai-skill-manager
```
配置文件:
```text
%APPDATA%\sgg-ai-skill-manager\config.json
```
状态文件:
```text
%APPDATA%\sgg-ai-skill-manager\state.json
```
本地仓库目录:
```text
%APPDATA%\sgg-ai-skill-manager\repos\{org}\{repo}
```
Codex skill 目录:
```text
C:\Users\{user}\.codex\skills
```
Claude skill 目录:
```text
C:\Users\{user}\.claude\skills
```
## 认证设计
配置页提供两种认证方式:
- 账号密码认证,作为默认方式。
- Token 认证,作为可选方式。
敏感信息不明文写入 `config.json`。配置文件只保存认证方式和凭据引用标识,真实密码或 Token 优先保存到 Windows Credential Manager。
如果 Windows Credential Manager 写入失败,保存配置失败并提示用户,不降级为明文保存。
Gitea API 调用规则:
- 账号密码模式使用 Basic Auth。
- Token 模式使用 `Authorization: token <token>`
Git clone 和 pull 的认证规则:
- 首版优先调用系统 `git`
- 账号密码或 Token 仅在执行 git 命令时从 Credential Manager 读取到内存中使用,不写入 `config.json``state.json` 或仓库 remote URL。
- clone 后仓库 remote URL 保存为不含密码和 Token 的普通 HTTPS URL。
- 如果认证失败,错误显示在对应仓库状态上,不阻塞整个应用。
## Gitea 仓库发现
远程市场页通过 Gitea API 读取组织仓库:
```http
GET /api/v1/orgs/{org}/repos
```
列表需要分页加载。每个仓库再检查根目录是否存在 `SKILL.md`。只有检查通过的仓库出现在远程市场页。
远程市场页展示字段:
- 仓库名
- 描述
- 默认分支
- 最近更新时间
- 本地状态:未下载、已下载、可更新、检查失败
搜索行为:
- 首版在已加载的远程仓库结果中按名称和描述进行本地过滤。
- 后续可以扩展为服务端搜索。
## 页面设计
### 配置页
配置项:
- Gitea baseURL
- 认证方式:账号密码或 Token
- 用户名
- 密码
- Token
- 组织名
- 自动更新开关,默认开启
- 启动时检查更新开关,默认开启
- 定时检查间隔,默认 60 分钟
操作:
- 保存配置
- 测试连接
测试连接需要验证:
- baseURL 可访问
- 凭据有效
- 当前账号能访问指定组织
### 远程市场页
远程市场页用于发现和下载 skill。
主要控件:
- 搜索框
- 刷新按钮
- 仓库列表
仓库操作:
- 下载:本地不存在时执行 `git clone`
- 更新:本地存在时执行更新检查和 `git pull`
- 打开本地:本地存在时打开目录
下载目标:
```text
%APPDATA%\sgg-ai-skill-manager\repos\{org}\{repo}
```
### 本地管理页
本地管理页用于管理已下载 skill 和目标应用安装状态。
建议使用表格布局,字段包括:
- 名称
- 本地路径
- 当前 commit
- 更新状态
- Codex 安装状态
- Claude 安装状态
- 操作
操作包括:
- 手动更新
- 安装到 Codex
- 卸载 Codex
- 安装到 Claude
- 卸载 Claude
- VS Code 打开
- 文件夹打开
- 删除本地
VS Code 打开使用:
```powershell
code . -n
```
命令执行目录为对应 skill 本地仓库目录。
文件夹打开使用 Windows 资源管理器打开对应目录。
## Junction 安装语义
安装到 Codex 或 Claude 时,不复制 skill 文件,而是在目标 skills 目录创建同名 Junction。
示例:
```text
C:\Users\{user}\.codex\skills\{repo}
-> %APPDATA%\sgg-ai-skill-manager\repos\{org}\{repo}
C:\Users\{user}\.claude\skills\{repo}
-> %APPDATA%\sgg-ai-skill-manager\repos\{org}\{repo}
```
安装规则:
- 如果目标 skills 目录不存在,安装时创建该目录。
- 如果目标路径不存在,创建 Junction。
- 如果目标路径是本软件记录的 Junction且指向当前 skill 本地路径,可以重建或保持不变。
- 如果目标路径是普通目录、文件、或指向其他位置的 Junction标记为冲突不自动删除。
- 安装成功后写入 `state.json`
卸载规则:
- 只卸载本软件记录的目标。
- 删除前再次确认目标是 Junction且指向当前 skill 本地路径。
- 确认通过后,只删除 Junction 本身,不删除本地 skill 仓库。
- 如果目标不是预期 Junction卸载失败并提示冲突。
删除本地 skill 规则:
- 如果 skill 已安装到 Codex 或 Claude先卸载对应 Junction。
- 如果任一 Junction 无法安全卸载,则阻止删除本地仓库。
- Junction 清理完成后,再删除本地仓库目录。
## 后端模块
### config
职责:
- 读取和保存 `config.json`
- 管理自动更新设置。
- 管理 Credential Manager 中的密码或 Token 引用。
### gitea
职责:
- 测试连接。
- 读取组织仓库。
- 检查仓库根目录 `SKILL.md`
- 获取仓库默认分支和远程最新 commit。
### gitops
职责:
- 检查系统 `git` 是否可用。
- 执行 clone。
- 执行 fetch 和 pull。
- 获取当前 commit。
- 获取远程 commit。
- 检测工作区是否存在未提交改动。
### skillstore
职责:
- 管理本地仓库目录。
- 读取和保存 `state.json`
- 记录本地 skill 元数据。
- 根据本地路径扫描已下载 skill。
### targets
职责:
- 管理 Codex 和 Claude 两个目标应用。
- 检测目标 skills 目录是否存在。
- 创建 Junction。
- 识别 Junction 目标。
- 卸载 Junction。
- 识别安装冲突。
### updater
职责:
- 启动后执行更新检查。
- 按配置间隔执行定时检查。
- 对无本地改动的已下载 skill 自动 pull。
- 记录更新失败原因。
## 状态文件设计
`config.json` 示例:
```json
{
"gitea": {
"baseURL": "https://gitea.example.com",
"org": "ai-skills",
"authType": "password",
"username": "user",
"credentialKey": "sgg-ai-skill-manager:gitea"
},
"update": {
"autoUpdate": true,
"checkOnStartup": true,
"intervalMinutes": 60
}
}
```
`state.json` 示例:
```json
{
"skills": [
{
"org": "ai-skills",
"repo": "lark-base",
"localPath": "C:\\Users\\wdh\\AppData\\Roaming\\sgg-ai-skill-manager\\repos\\ai-skills\\lark-base",
"remoteURL": "https://gitea.example.com/ai-skills/lark-base.git",
"defaultBranch": "main",
"currentCommit": "abc123",
"lastCheckedAt": "2026-05-13T14:00:00+08:00",
"lastError": "",
"installedTargets": {
"codex": {
"path": "C:\\Users\\wdh\\.codex\\skills\\lark-base",
"linkType": "junction",
"targetPath": "C:\\Users\\wdh\\AppData\\Roaming\\sgg-ai-skill-manager\\repos\\ai-skills\\lark-base"
},
"claude": {
"path": "C:\\Users\\wdh\\.claude\\skills\\lark-base",
"linkType": "junction",
"targetPath": "C:\\Users\\wdh\\AppData\\Roaming\\sgg-ai-skill-manager\\repos\\ai-skills\\lark-base"
}
}
}
]
}
```
## 自动更新策略
默认开启自动更新。
启动时:
1. 读取 `state.json`
2. 对已下载 skill 执行更新检查。
3. 如果远程 commit 比本地新,且本地没有未提交改动,执行 `git pull`
4. 如果 skill 已安装到 Codex 或 Claude因为目标应用读取的是 Junctionpull 完成本身即完成同步。
5. 如果更新失败,记录错误并在本地管理页显示。
定时检查:
- 按配置的分钟间隔执行。
- 同一时刻只允许一个更新任务运行。
- 用户手动更新时,如果后台正在更新同一个 skill需要返回“正在更新”状态。
本地改动处理:
- 如果发现本地仓库有未提交改动,不执行自动更新。
- 状态显示为“本地有改动”。
- 首版允许用户打开目录或 VS Code 手动处理。
- 首版不自动 stash、reset 或覆盖本地改动。
## 错误处理
错误状态应落到具体对象上,避免一个仓库失败影响其他仓库。
常见错误:
- Gitea baseURL 不可访问。
- 凭据无效。
- 当前账号无组织访问权限。
- 仓库没有 `SKILL.md`
- 系统未安装 `git``git` 不在 PATH。
- clone 或 pull 认证失败。
- 本地仓库存在未提交改动。
- 目标 skills 目录不存在。
- 目标路径存在同名普通目录。
- 目标路径存在未知 Junction。
- Junction 删除前校验失败。
用户可见错误需要包含:
- 失败对象,例如仓库名或目标应用名。
- 简短原因。
- 可执行建议,例如“检查配置”“打开本地目录处理改动”“手动处理同名目录”。
## 安全规则
- 不自动删除用户已有普通目录。
- 不自动删除未知 Junction。
- 不自动覆盖本地仓库未提交改动。
- 不明文保存 Gitea 密码或 Token。
- 删除本地 skill 前必须先安全清理本软件创建的 Junction。
- 所有路径操作使用绝对路径。
- 删除操作限定在应用管理目录或记录中的目标 Junction 路径内。
## 验收标准
配置:
- 能保存 Gitea baseURL、认证方式、账号密码或 Token、组织名。
- 能测试连接并识别组织访问权限。
- 敏感信息不出现在 `config.json` 明文中。
远程市场:
- 能读取组织仓库列表。
- 只展示根目录存在 `SKILL.md` 的仓库。
- 能按名称和描述搜索。
- 能下载未下载 skill。
- 能更新已下载 skill。
本地管理:
- 能展示已下载 skill 的路径、commit 和安装状态。
- 能安装到 Codex。
- 能安装到 Claude。
- 安装结果是 Junction不是目录复制。
- 能卸载 Codex 和 Claude 的 Junction。
- 卸载不会删除本地仓库。
- 能删除本地 skill并先清理本软件创建的 Junction。
- 遇到同名普通目录或未知 Junction 时不会自动覆盖。
- 能用 VS Code 打开 skill 目录。
- 能用资源管理器打开 skill 目录。
自动更新:
- 启动时能检查已下载 skill 是否有更新。
- 无本地改动时能自动 pull。
- 已安装 skill 更新后Codex 和 Claude 通过 Junction 能读取最新内容。
- 有本地未提交改动时不会自动覆盖。
## 后续扩展方向
首版采用轻量 MVP但保留模块边界后续可以扩展
- 更多目标应用。
- 多个 Gitea 组织。
- 多个代码托管源。
- 批量操作。
- 更新日志和版本回滚。
- skill 元数据解析和分类。