forked from chroe/gitlink-cli
405 lines
16 KiB
Markdown
405 lines
16 KiB
Markdown
# GitLink-CLI 项目状态总结
|
||
|
||
> 最后更新:2026-06-08
|
||
> 仓库:`D:\自用\self\word\大三下\软件演化\gitlink-cli`
|
||
> 远程:`https://gitlink.org.cn/chroe/gitlink-cli.git`
|
||
|
||
---
|
||
|
||
## 一、课程任务背景
|
||
|
||
**课程**:《软件演化与运维》课程实践
|
||
**进阶任务**:GitLink 智能化能力提升项目
|
||
**当前阶段**:子任务二 — 编写和丰富 GitLink Skills(20%,截止 6月18日)
|
||
|
||
### 子任务一交付要求(已完成)
|
||
- 向 gitlink-cli 主仓库提交 PR(可多个)
|
||
- 每个 PR 包含:功能代码 + 单元测试 + 命令帮助文档更新
|
||
- 提供变更说明文档
|
||
- 撰写《软件分析及建模报告》、《新需求构思报告》、《变更影响分析及测试报告》
|
||
|
||
### 子任务二交付要求(进行中)
|
||
- 遵循 gitlink-cli Skills 规范(参考 `skills/README.md`)
|
||
- 每个 Skill 包含:SKILL.md + 使用示例 + 至少在一个 Agent 平台上验证通过
|
||
- 兼容至少一个主流 AI Agent(如 Claude Code、OpenClaw、Cursor 等)
|
||
- 撰写《新需求构思报告》和《变更影响分析及测试报告》
|
||
|
||
---
|
||
|
||
## 二、技术栈与架构
|
||
|
||
- **语言**:Go 1.26.1
|
||
- **CLI 框架**:spf13/cobra
|
||
- **密钥存储**:zalando/go-keyring(OS keychain + 文件 fallback)
|
||
- **配置**:gopkg.in/yaml.v3,存放于 `~/.config/gitlink-cli/config.yaml`
|
||
- **三层命令架构**:
|
||
1. **基础命令**(cmd/):`auth`, `api`, `config`, `version`
|
||
2. **Shortcut 命令**(shortcuts/):`repo +list`, `issue +create` 等 94 个命令
|
||
3. **Raw API**:`api GET /path`
|
||
|
||
### Shortcut 模块开发模式
|
||
|
||
每个模块位于 `shortcuts/<name>/<name>.go`,结构固定:
|
||
|
||
```go
|
||
package <name>
|
||
|
||
import "github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
||
|
||
func Shortcuts() []*common.Shortcut {
|
||
return []*common.Shortcut{
|
||
{
|
||
Name: "list",
|
||
Description: "Description here",
|
||
Flags: []common.Flag{
|
||
{Name: "page", Short: "p", Usage: "Page number", Default: "1"},
|
||
},
|
||
Run: func(ctx *common.RuntimeContext) error {
|
||
if err := ctx.ResolveOwnerRepo(); err != nil { return err }
|
||
env, err := ctx.CallAPI("GET", ctx.RepoPath()+"/something", nil)
|
||
if err != nil { return err }
|
||
return ctx.Output(env)
|
||
},
|
||
},
|
||
}
|
||
}
|
||
```
|
||
|
||
注册到 `shortcuts/register.go`:
|
||
```go
|
||
import "github.com/gitlink-org/gitlink-cli/shortcuts/<name>"
|
||
// 在 RegisterAll() 中添加:
|
||
// "<name>": <name>.Shortcuts(),
|
||
// descriptions["<name>"] = "Description",
|
||
```
|
||
|
||
### 单元测试模式(httptest mock)
|
||
|
||
```go
|
||
func TestXxx(t *testing.T) {
|
||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
// 校验 method/path/query,返回 mock JSON
|
||
}))
|
||
defer server.Close()
|
||
|
||
ctx := &common.RuntimeContext{
|
||
Client: &client.Client{HTTP: server.Client(), BaseURL: server.URL},
|
||
Owner: "owner", Repo: "repo", Format: "json", Args: args,
|
||
}
|
||
err := findShortcut(t, "list").Run(ctx)
|
||
// 断言
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、已实现的 18 个 Shortcut 模块(94 个命令)
|
||
|
||
| 模块 | 命令数 | 文件 | 测试 |
|
||
|------|--------|------|------|
|
||
| repo | 9(含 batch-delete/fork) | shortcuts/repo/ | ✅ |
|
||
| issue | 12(含 batch-close/assign/label/milestone) | shortcuts/issue/ | ✅ |
|
||
| pr | 9 | shortcuts/pr/ | ✅ |
|
||
| release | 5 | shortcuts/release/ | ✅ |
|
||
| branch | 5 | shortcuts/branch/ | ✅ |
|
||
| ci | 4 | shortcuts/ci/ | ✅ |
|
||
| commit | 4 | shortcuts/commit/ | ✅ |
|
||
| file | 5 | shortcuts/file/ | ✅ |
|
||
| member | 4 | shortcuts/member/ | ✅ |
|
||
| star | 3 | shortcuts/star/ | ✅ |
|
||
| watch | 3 | shortcuts/watch/ | ✅ |
|
||
| label | 4 | shortcuts/label/ | ✅ |
|
||
| milestone | 6 | shortcuts/milestone/ | ✅ |
|
||
| webhook | 6 | shortcuts/webhook/ | ✅ |
|
||
| org | 5(含 batch-invite) | shortcuts/org/ | ✅ |
|
||
| search | 3 | shortcuts/search/ | ✅ |
|
||
| user | 2 | shortcuts/user/ | ✅ |
|
||
| wiki 🆕 | 5 | shortcuts/wiki/ | ✅ 12个测试 |
|
||
|
||
### 批量操作汇总(7个)
|
||
|
||
| 批量命令 | 所属模块 | 输入方式 | 预览模式 |
|
||
|----------|----------|----------|----------|
|
||
| batch-close | issue | --numbers 逗号 / --from CSV | --dry-run |
|
||
| batch-assign | issue | 同上 | --dry-run |
|
||
| batch-label | issue | 同上 | --dry-run |
|
||
| batch-milestone | issue | 同上 | --dry-run |
|
||
| batch-delete | repo | --repos owner/repo 列表 / --from CSV | --dry-run |
|
||
| batch-fork | repo | 同上 | --dry-run |
|
||
| batch-invite | org | --users 用户名列表 / --from CSV | --dry-run |
|
||
|
||
---
|
||
|
||
## 四、Wiki 模块开发记录
|
||
|
||
### Wiki API 关键发现
|
||
|
||
| 发现 | 说明 |
|
||
|------|------|
|
||
| API 域名 | `gateway.gitlink.org.cn` 而非 `www.gitlink.org.cn` |
|
||
| API 路径 | `/wiki/open/...`(有 `/open/` 中间段) |
|
||
| 无 `.json` 后缀 | Gateway 不接受 `.json`,需要 `client.DoRaw()` |
|
||
| Sidebar 名称 | `_Sidebar`(大写 S),非小写 `_sidebar` |
|
||
| projectId 字段 | 仓库返回 `project_id` 而非 `id` |
|
||
| create/update 需要 `title` | API 必填字段 |
|
||
| delete 异步重建 sidebar | 需延迟 2 秒后再清理 sidebar |
|
||
| `data.data` 格式 | `DoRaw` 返回 dict 而非 string,解析需兼容 |
|
||
|
||
### delete 命令的 sidebar 自动清理流程
|
||
1. 删除 wiki 页面(DELETE)
|
||
2. 等待 2 秒(让 GitLink 完成异步 sidebar 重建)
|
||
3. 获取 `_Sidebar` 内容
|
||
4. 移除已删页面的 `[[PageName]]` 链接
|
||
5. 更新 `_Sidebar`
|
||
|
||
---
|
||
|
||
## 五、开发踩坑记录
|
||
|
||
### 修改 CLI 代码后必须同时重建 showcase
|
||
showcase 通过 `findCLIBinary()` 在运行时查找 `gitlink-cli.exe`。每次修改 CLI 代码后需要:
|
||
```bash
|
||
cd gitlink-cli
|
||
go build -o gitlink-cli.exe . # 重建 CLI
|
||
cd showcase && go build -o showcase.exe . # 重建 showcase(更新嵌入的 HTML)
|
||
# 然后重启 showcase.exe
|
||
```
|
||
如果只重建 showcase 不重建 CLI,showcase 用的还是旧版二进制。
|
||
|
||
### Showcase 参数传递坑
|
||
showcase 后端曾用 `strings.Split(args, " ")` 按空格切割参数,导致 `"Hello Wiki!"` 被截断为 `"Hello"`。
|
||
修复:前端给含空格的值加引号,后端用支持引号解析的 `parseShellArgs()` 替代简单 Split。
|
||
|
||
### Showcase 布尔参数坑(已修复)
|
||
Cobra 的 BoolP 标志:`--dry-run false`(空格分隔)会被解析为 `--dry-run=true` + 多余参数 "false"。
|
||
所以批量操作 `--dry-run false` 实际上是在预览模式下运行,不会真正执行。
|
||
修复:布尔参数改用 `<select>` 下拉框,JS 只在选"是"时才传 `--flag`,选"否"时不传。
|
||
|
||
### Showcase 重复参数坑(已修复)
|
||
服务器后端自动添加 `--owner chroe --repo gitlink-cli`。如果前端卡片也传 `--owner`/`--repo`,
|
||
会导致参数重复。修复:watch +watchers 和 star +stars 移除了多余的 owner/repo 输入框。
|
||
|
||
### Showcase null 显示(已修复)
|
||
CLI 命令返回空数据时,前端显示 "null"。修复:JS 层对 null/空对象/空字符串统一显示"操作完成,无返回数据"。
|
||
|
||
---
|
||
|
||
## 六、CI/CD 流水线
|
||
|
||
### 部署架构
|
||
```
|
||
代码 push → GitLink 触发流水线 → SSH 到服务器 → git fetch + reset → docker build → 重启容器
|
||
```
|
||
|
||
### 流水线文件
|
||
- `.devops/构建部署Showcase.yml` — GitLink DevOps 流水线(push 自动触发)
|
||
|
||
### 流水线关键配置
|
||
- 使用 `git fetch + git reset --hard origin/master` 避免 git pull 的本地修改冲突
|
||
- 使用 `docker build --no-cache` 确保每次用最新代码构建
|
||
- 容器启动时注入 `-e GITLINK_TOKEN=cookie:autologin_trustie=...` 解决认证问题
|
||
- GitLink 密钥管理:`deploy_server.server_password` = 服务器密码
|
||
|
||
### 服务器信息
|
||
- **IP**: 118.31.4.168
|
||
- **用户**: root
|
||
- **部署路径**: /opt/gitlink-cli
|
||
- **容器名**: gitlink-cli-showcase
|
||
- **端口**: 9090
|
||
- **访问地址**: http://118.31.4.168:9090
|
||
- **Showcase 展示模块数**: 12 个模块卡片(milestone/webhook/label/commit/wiki/file/member/watch/star/issue批量/repo批量/org批量)
|
||
|
||
### Docker 构建注意
|
||
Dockerfile 已配置 `ENV GOPROXY=https://goproxy.cn,direct`,解决国内网络 Go 模块下载问题。
|
||
服务器 Docker daemon 已配置国内镜像加速器(`/etc/docker/daemon.json`)。
|
||
|
||
---
|
||
|
||
## 七、已完成工作
|
||
|
||
### ✅ 子任务一完成项
|
||
- [x] 基础命令框架(auth/api/config/version)
|
||
- [x] 18 个 Shortcut 模块(94 个命令),其中 wiki 为新增
|
||
- [x] 7 个批量操作命令(batch-close/assign/label/milestone/delete/fork/invite)
|
||
- [x] 12 个 AI Agent Skills(基础版,部分需要丰富)
|
||
- [x] Showcase Dashboard 在线展示(12 个模块卡片,支持真实运行)
|
||
- [x] GitHub CI/CD(release + npm publish + FreeBSD 支持)
|
||
- [x] GitLink DevOps 流水线(push 自动部署,已配置密钥,正常运行)
|
||
- [x] 单元测试(wiki 12个 + 其他模块 47+)
|
||
- [x] client.DoRaw 方法(不带 .json 后缀的原始 API 调用)
|
||
- [x] Showcase 布尔参数/重复参数/null显示 修复
|
||
|
||
---
|
||
|
||
## 七-A、子任务二:编写和丰富 GitLink Skills
|
||
|
||
### 📋 总体策略
|
||
1. **先做新 Skill**:开发课程建议的新场景 Skill
|
||
2. **后完善老 Skill**:丰富已有的 12 个 Skill,补充 REFERENCE.md、examples、验证记录
|
||
|
||
### 新 Skill 开发进度
|
||
|
||
| 优先级 | Skill 名称 | 场景 | 状态 | 说明 |
|
||
|--------|-----------|------|------|------|
|
||
| 🥇 | `gitlink-health` | 项目健康度报告 | ✅ 已完成 | 评分算法验证通过,含 fallback 策略 |
|
||
| 🥈 | `gitlink-changelog` | Release Notes 自动生成 | ✅ 已完成 | commit 分类规则完整,含 PR 过滤注意事项 |
|
||
| 🥉 | `gitlink-triage` | Issue 智能分拣 + 新人引导 | ✅ 已完成 | 含 subject/description 保留警告、标签映射说明 |
|
||
|
||
### Skill 开发指南(给队友看的)
|
||
|
||
> 完整踩坑记录见 `EXPERIMENT_LOG.md`,这里只写怎么动手。
|
||
|
||
#### 每个 Skill 的标准交付物(3 个文件)
|
||
|
||
```
|
||
skills/gitlink-<name>/
|
||
├── SKILL.md # 主文件:触发条件、数据采集命令、输出格式、使用场景
|
||
├── REFERENCE.md # 技术参考:字段映射、API 注意事项、Q&A
|
||
└── examples/
|
||
└── <scenario>.md # 使用示例(= Agent 验证证明)
|
||
```
|
||
|
||
**不需要** VERIFICATION.md — example 里放真实命令输出,本身就是验证记录。
|
||
|
||
#### 开发步骤(按顺序做)
|
||
|
||
```
|
||
第一步:确定场景
|
||
- 这个 Skill 解决什么问题?什么时候触发?
|
||
|
||
第二步:写 SKILL.md
|
||
- 照着已有的 Skill 抄格式(推荐抄 gitlink-issue/SKILL.md)
|
||
- 必须有的内容:
|
||
· frontmatter(name/version/description/metadata)
|
||
· CRITICAL 块引用 gitlink-shared/SKILL.md
|
||
· 数据采集命令(分步骤,每步一个代码块)
|
||
· 输出格式模板
|
||
· 2-3 个使用场景
|
||
· 最佳实践
|
||
|
||
第三步:⚠️ 在终端里逐条跑 SKILL.md 中的命令(最重要!)
|
||
- 每条命令都要跑,看返回的是 JSON 还是 HTML
|
||
- 写入命令确认参数完整、能执行
|
||
- 记录每条命令的真实输出(后面写 example 要用)
|
||
|
||
第四步:写 REFERENCE.md
|
||
- API 字段映射(命令返回的 JSON 长什么样)
|
||
- 注意事项和限制
|
||
- 常见问题 Q&A
|
||
|
||
第五步:写 examples/
|
||
- 用第三步记录的真实输出
|
||
- 格式:命令序列 + 真实返回数据 + AI 生成的结果
|
||
- 不准编造数据!
|
||
```
|
||
|
||
#### ⚠️ 绝对不能踩的坑
|
||
|
||
| 坑 | 说明 | 怎么避 |
|
||
|----|------|--------|
|
||
| `api` 子命令不可用 | `gitlink-cli api GET/POST` 存在 URL 污染 bug,会把 git 安装路径拼进 URL | **不要用** `api` 子命令,只用 shortcut 命令(如 `issue +list`、`repo +info`) |
|
||
| `--state open` 过滤不准 | `issue +list --state open` 可能返回已关闭的 Issue | 客户端检查 `status_id`,`5` = 关闭 |
|
||
| journals API 返回 HTML | `/v1/:owner/:repo/issues/:number/journals` 返回网页 | 用 `issue +view` 的 `comment_journals_count` 字段代替 |
|
||
| compare API 返回 HTML | `/owner/:repo/compare/...` 返回网页 | 用 `commit +list` 按时间筛选代替 |
|
||
| Issue 更新会清空字段 | 更新时不带 subject/description 会导致标题和描述被清空 | 先 `issue +view` 获取当前内容,更新时一并提交 |
|
||
| 标签名是中文 | 项目已有标签是"缺陷/功能/疑问",不是英文 | 用 `label +list` 获取已有标签,优先匹配 |
|
||
| `issue +update` 不支持打标签/分配 | 只有 title/body/state 三个参数 | 写入 CRITICAL 警告,引导用户网页操作 |
|
||
|
||
#### 已有 Skill 完善任务分配
|
||
|
||
| Skill | 当前状态 | 要做的事 | 分配给 |
|
||
|-------|---------|---------|--------|
|
||
| **gitlink-issue** | 有 SKILL.md + references/(7个文件) | 补 examples/(用 chroe/gitlink-cli 真实数据) | — |
|
||
| **gitlink-pr** | 有 SKILL.md + references/(6个文件) | 补 examples/ | — |
|
||
| **gitlink-release** | 有 SKILL.md + references/(4个文件) | 补 examples/ | — |
|
||
| **gitlink-workflow** | 仅有空壳 SKILL.md | 重写 SKILL.md + 补 REFERENCE.md + examples | — |
|
||
| **gitlink-ci** | 仅有 SKILL.md | 补 REFERENCE.md + examples | — |
|
||
| **gitlink-pm** | 仅有 SKILL.md | 补 REFERENCE.md + examples | — |
|
||
| **gitlink-repo** | 有 SKILL.md + references/(9个文件) | 补 examples/ | — |
|
||
| **gitlink-search** | 有 SKILL.md + references/(2个文件) | 补 examples/ | — |
|
||
| **gitlink-user** | 有 SKILL.md + references/(2个文件) | 补 examples/ | — |
|
||
| **gitlink-org** | 有 SKILL.md + references/(3个文件) | 补 examples/ | — |
|
||
| **gitlink-branch** | 有 SKILL.md + examples/(1个文件) | 补 REFERENCE.md | — |
|
||
|
||
> **完善标准**:每个 Skill 至少有 SKILL.md + examples/(含真实命令输出)。REFERENCE.md 如果已有 references/ 目录可以不写。
|
||
|
||
### 待写文档 📄
|
||
- [ ] 《新需求构思报告》(子任务一 + 子任务二共用)
|
||
- [ ] 《变更影响分析及测试报告》(子任务一 + 子任务二共用)
|
||
|
||
---
|
||
|
||
## 八、小组分工
|
||
|
||
| 角色 | 负责人 | 负责内容 |
|
||
|------|--------|----------|
|
||
| 组长 A | — | commit(4命令)、milestone(6)、webhook(6)、label(4)、Showcase |
|
||
| 同学 B | — | file(5)、member(4)、watch(3)、star(3) |
|
||
| 同学 C | — | 批量操作增强(batch-assign/label/milestone/delete/fork/invite)、table 输出优化、测试覆盖、FreeBSD构建 |
|
||
| 全员 | — | wiki(5命令)、流水线部署 |
|
||
|
||
---
|
||
|
||
## 九、快速开始
|
||
|
||
```bash
|
||
# 构建
|
||
cd gitlink-cli && make build
|
||
|
||
# 运行测试
|
||
go test ./shortcuts/... -v
|
||
|
||
# 登录
|
||
./gitlink-cli auth login
|
||
|
||
# 使用示例
|
||
./gitlink-cli repo +list --owner gitlink
|
||
./gitlink-cli issue +list --owner gitlink --repo gitlink-cli
|
||
./gitlink-cli wiki +list --owner chroe --repo gitlink_help_center
|
||
```
|
||
|
||
---
|
||
|
||
## 十、当前进度 & 下一步
|
||
|
||
### 子任务一 ✅ 已完成
|
||
1. 全部 18 个 Shortcut 模块 + 94 个命令
|
||
2. 7 个批量操作命令
|
||
3. Showcase 展示页(12 个模块,可在线运行)
|
||
4. GitLink DevOps 流水线(push 自动部署)
|
||
5. 单元测试 47+ 个
|
||
6. Showcase 各种 bug 修复(布尔参数、null 显示、重复参数、member ID 提示)
|
||
7. 12 个 AI Agent Skills(基础版)
|
||
|
||
### 子任务二 🔄 进行中(截止 6月18日)
|
||
|
||
#### 第一步:开发新 Skill ✅ 已完成
|
||
- [x] `gitlink-health` — 项目健康度报告 Skill
|
||
- [x] SKILL.md(主文件 + CRITICAL 读 REFERENCE)
|
||
- [x] REFERENCE.md(评分算法 + fallback 策略 + 社区关注度标准)
|
||
- [x] examples/(健康度报告 + 周报,2026-06-08 真实数据)
|
||
- [x] VERIFICATION.md(Claude Code 验证通过)
|
||
- [x] 公平评分验证:77/100(严格按公式计算)
|
||
- [x] `gitlink-changelog` — Release Notes 自动生成 Skill
|
||
- [x] SKILL.md(CRITICAL 读 REFERENCE + 完整分类规则)
|
||
- [x] REFERENCE.md(API 路径修正 + PR 过滤注意事项)
|
||
- [x] examples/(changelog 生成示例,真实数据)
|
||
- [x] VERIFICATION.md(Claude Code 验证通过)
|
||
- [x] `gitlink-triage` — Issue 智能分拣 + 新人引导 Skill
|
||
- [x] SKILL.md(CRITICAL 读 REFERENCE + subject 保留警告)
|
||
- [x] REFERENCE.md(颜色码修正 + 标签映射说明)
|
||
- [x] examples/(6 Issue 批量分拣示例,真实数据)
|
||
- [x] VERIFICATION.md(Claude Code 验证通过)
|
||
|
||
#### 第二步:完善已有 Skill
|
||
- [ ] gitlink-workflow 升级为独立完整 Skill(当前仅为简单骨架)
|
||
- [ ] 补充 gitlink-ci、gitlink-pm 的 REFERENCE.md + examples
|
||
- [ ] 为所有 Skill 补充 VERIFICATION.md
|
||
|
||
#### 第三步:文档撰写
|
||
- [ ] 向 gitlink-cli 主仓库提交 Skills PR
|
||
- [ ] 撰写《软件分析及建模报告》
|
||
- [ ] 撰写《新需求构思报告》
|
||
- [ ] 撰写《变更影响分析及测试报告》
|
||
- [ ] 变更说明文档
|