gitlink-cli/doc/design.md

813 lines
29 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.

# gitlink-cli 整体设计文档
## Context
GitLink确实开源是 CCF 官方开源协作平台Forgeplus 后端提供 490+ API 端点,但缺少官方 CLI 工具。本项目采用业界主流的分层 CLI 架构Shortcuts → API Commands → Raw API开发 gitlink-cli覆盖高频 Git Forge 场景,并内置 AI Agent Skills 支持 Claude Code 自动化操作。
**设计原则**单实例gitlink.org.cn、Go + Cobra、三层命令体系、Claude Code Skills 优先。
---
## 1 项目结构
```
gitlink-cli/
├── cmd/
│ ├── root.go # 根命令、全局 flags
│ ├── auth/ # auth login / logout / status
│ ├── api/ # api GET/POST/PUT/DELETE原始层
│ ├── config/ # config init / set / get / list
│ └── service/ # 元数据驱动的 API 命令层
├── internal/
│ ├── auth/
│ │ ├── login.go # 用户名密码登录 + Token 粘贴
│ │ ├── token_store.go # OS Keychain 存储
│ │ └── transport.go # http.RoundTripper 自动注入 Token
│ ├── client/
│ │ ├── client.go # HTTP 客户端 + 错误解包
│ │ └── pagination.go # Kaminari 分页迭代器
│ ├── config/
│ │ └── config.go # ~/.config/gitlink-cli/config.yaml
│ ├── output/
│ │ ├── envelope.go # {ok, data, error, meta} 标准输出
│ │ └── formatter.go # --format json/table/yaml
│ ├── context/
│ │ └── repo.go # git remote → owner/repo 自动解析
│ └── registry/
│ ├── loader.go # 元数据加载(内嵌 JSON
│ └── meta_data.json # API 元数据(路径、参数、说明)
├── shortcuts/
│ ├── common/
│ │ ├── types.go # Shortcut / Flag / RuntimeContext 定义
│ │ └── runner.go # CallAPI / PaginateAll / ResolveOwnerRepo
│ ├── repo/ # repo +create / +clone / +fork / +list / +info / +delete / +settings / +batch-create / +batch-update
│ ├── issue/ # issue +list / +create / +view / +update / +close / +comment / +assign / +label / +batch-* (6 个批量命令)
│ ├── wiki/ # wiki +list / +view / +create / +update / +delete
│ ├── pr/ # pr +list / +create / +view / +merge / +close / +review / +files / +diff
│ ├── release/ # release +list / +create / +view / +delete / +download
│ ├── branch/ # branch +list / +create / +delete / +protect / +unprotect
│ ├── webhook/ # webhook +list / +create / +update / +delete / +test / +info
│ ├── org/ # org +list / +info / +members / +create
│ ├── user/ # user +me / +info
│ ├── search/ # search +repos / +issues / +users
│ ├── ci/ # ci +builds / +logs / +restart / +stop
│ └── register.go # 注册所有 shortcuts 到 cobra
├── skills/
│ ├── gitlink-shared/ # SKILL.md — 认证、全局参数、安全规则
│ ├── gitlink-repo/ # SKILL.md + references/ — 仓库操作
│ ├── gitlink-issue/ # SKILL.md + references/ — Issue 操作
│ ├── gitlink-pr/ # SKILL.md + references/ — PR 操作
│ ├── gitlink-release/ # SKILL.md + references/ — 发布管理
│ ├── gitlink-branch/ # SKILL.md + references/ — 分支操作
│ ├── gitlink-ci/ # SKILL.md + references/ — CI/CD 操作
│ ├── gitlink-org/ # SKILL.md + references/ — 组织管理
│ ├── gitlink-search/ # SKILL.md + references/ — 搜索
│ ├── gitlink-user/ # SKILL.md + references/ — 用户管理
│ ├── gitlink-pm/ # SKILL.md + references/ — 项目管理
│ ├── gitlink-wiki/ # SKILL.md + references/ + examples/ — Wiki 操作
│ ├── gitlink-webhook/ # SKILL.md + references/ + examples/ — Webhook 管理
│ └── gitlink-workflow/ # SKILL.md + references/ + examples/ — AI 自动化工作流Issue 分类、PR Review 等)
├── go.mod
├── go.sum
├── Makefile
└── README.md
```
---
## 2 三层命令体系
### 2.1 Layer 1: Shortcuts快捷命令`+` 前缀)
面向高频场景的语义化封装,覆盖 13 个领域共 62 个命令:
| 领域 | Shortcuts | 数量 |
|------|-----------|------|
| repo | `+create` `+clone` `+fork` `+list` `+info` `+delete` `+settings` `+batch-create` `+batch-update` | 9 |
| issue | `+list` `+create` `+view` `+update` `+close` `+comment` `+assign` `+label` `+batch-close` `+batch-status` `+batch-priority` `+batch-assign` `+batch-label` `+batch-create` | 14 |
| wiki | `+list` `+view` `+create` `+update` `+delete` | 5 |
| pr | `+list` `+create` `+view` `+merge` `+close` `+review` `+files` `+diff` | 8 |
| release | `+list` `+create` `+view` `+delete` `+download` | 5 |
| branch | `+list` `+create` `+delete` `+protect` `+unprotect` | 5 |
| org | `+list` `+info` `+members` `+create` | 4 |
| ci | `+builds` `+logs` `+restart` `+stop` | 4 |
| user | `+me` `+info` | 2 |
| webhook | `+list` `+create` `+update` `+delete` `+test` `+info` | 6 |
**Shortcut 声明式定义**
```go
type Shortcut struct {
Name string
Description string
Flags []Flag
Run func(ctx *RuntimeContext) error
}
type Flag struct {
Name string
Short string
Usage string
Required bool
Default interface{}
}
```
**RuntimeContext 核心方法**
```go
type RuntimeContext struct {
Client *client.Client
Owner string // 自动从 git remote 解析或 --owner 指定
Repo string // 自动从 git remote 解析或 --repo 指定
Format string // json / table / yaml
}
func (ctx *RuntimeContext) CallAPI(method, path string, body interface{}) (*Envelope, error)
func (ctx *RuntimeContext) PaginateAll(path string, params url.Values) ([]json.RawMessage, error)
func (ctx *RuntimeContext) ResolveOwnerRepo() error // git remote 解析
func (ctx *RuntimeContext) Output(data interface{}) error
```
### 2.2 Layer 2: API Commands元数据驱动
自动从 `meta_data.json` 生成,覆盖 ~84 个常用端点:
```
gitlink-cli repos list
gitlink-cli repos get --owner foo --repo bar
gitlink-cli issues list --owner foo --repo bar --state open
gitlink-cli pulls create --owner foo --repo bar --title "..." --head dev --base main
```
元数据格式:
```json
{
"repos": {
"list": {
"method": "GET",
"path": "/api/:owner/:repo",
"params": {
"owner": {"type": "string", "required": true, "from": "path"},
"repo": {"type": "string", "required": true, "from": "path"}
},
"description": "获取仓库信息"
}
}
}
```
### 2.3 Layer 3: Raw API原始调用
```bash
gitlink-cli api GET /api/users/me
gitlink-cli api POST /api/:owner/:repo/issues --body '{"subject":"bug","description":"..."}'
gitlink-cli api GET /api/projects --query 'page=1&limit=10'
```
覆盖全部 490+ 端点,自动注入认证 Header。
---
## 3 认证Auth
### GitLink 认证特点
- OAuth2 (Doorkeeper) 签发 Bearer Token
- Token 有效期 7 天,到期需重新登录
- 不支持 OAuth Device Flow`/device/code` 端点)
### 认证流程
**方式 1用户名密码登录**
```bash
gitlink-cli auth login
# 交互式输入用户名和密码
# 调用 POST /api/accounts/login 获取 Token
# Token 存入 OS Keychain
```
**方式 2Token 粘贴**
```bash
gitlink-cli auth login --token
# 交互式粘贴已有 Token
# 存入 OS Keychain
```
**其他命令**
```bash
gitlink-cli auth status # 查看登录状态和 Token 过期时间
gitlink-cli auth logout # 清除 Token
```
### Token 存储
使用 `zalando/go-keyring` 库,跨平台:
- macOS: Keychain
- Linux: Secret Service (GNOME Keyring / KDE Wallet)
- Windows: Credential Manager
Fallback: `~/.config/gitlink-cli/credentials`(文件权限 0600
---
## 4 配置Config
配置文件:`~/.config/gitlink-cli/config.yaml`
```yaml
# 单实例,无需 instance 管理
base_url: https://www.gitlink.org.cn/api
default_format: table # json | table | yaml
editor: vim # Issue/PR 正文编辑器
pager: less # 长输出分页器
```
```bash
gitlink-cli config init # 首次初始化
gitlink-cli config set key val # 设置配置项
gitlink-cli config get key # 读取配置项
gitlink-cli config list # 列出所有配置
```
---
## 5 API 客户端
### 5.1 GitLink 响应特殊处理
GitLink API 常规错误返回 **HTTP 200 + JSON body 中 status 非 200**
```json
{"status": 403, "message": "You are not authorized"}
{"status": -1, "message": "参数错误"}
```
客户端必须在 HTTP 层和 JSON body 层双重检查:
```go
func (c *Client) Do(req *http.Request) (*Envelope, error) {
resp, err := c.http.Do(req)
// 1. 检查 HTTP 状态码
if resp.StatusCode >= 400 { ... }
// 2. 解析 JSON body
var raw map[string]interface{}
json.Decode(resp.Body, &raw)
// 3. 检查 body 中的 status 字段
if status, ok := raw["status"]; ok && status != 200 {
return nil, &APIError{Code: status, Message: raw["message"]}
}
// 4. 封装为标准 Envelope
return &Envelope{OK: true, Data: raw}, nil
}
```
### 5.2 分页
GitLink 使用 Kaminari 风格分页:
```
GET /api/projects?page=1&limit=20
→ Response headers: X-Total / X-Page / X-Limit
→ 或 body 中: total_count / page / limit
```
分页迭代器:
```go
func (c *Client) PaginateAll(path string, params url.Values) ([]json.RawMessage, error) {
var all []json.RawMessage
page := 1
for {
params.Set("page", strconv.Itoa(page))
resp, err := c.Get(path, params)
items := resp.Data.([]interface{})
if len(items) == 0 { break }
all = append(all, items...)
page++
}
return all, nil
}
```
### 5.3 输出 Envelope
统一输出格式:
```json
{
"ok": true,
"data": { ... },
"meta": {
"page": 1,
"limit": 20,
"total_count": 156,
"identity": "user:zhangsan"
}
}
```
错误格式:
```json
{
"ok": false,
"error": {
"code": 403,
"message": "You are not authorized",
"suggestion": "请先运行 gitlink-cli auth login 登录"
}
}
```
---
## 6 Git Remote 上下文解析
gitlink-cli 可从当前目录的 git remote 自动推断 `owner``repo`
```go
func ResolveOwnerRepo() (owner, repo string, err error) {
// 1. 检查 --owner/--repo flags
// 2. 解析 .git/config 中的 remote "origin" URL
// 支持: https://www.gitlink.org.cn/owner/repo.git
// git@www.gitlink.org.cn:owner/repo.git
// 3. 提取 owner 和 repo
}
```
使用示例:
```bash
cd ~/projects/my-gitlink-repo
gitlink-cli issue +list # 自动解析 owner/repo
gitlink-cli issue +list --owner foo --repo bar # 显式指定
```
---
## 7 Schema 自省
```bash
gitlink-cli schema list # 列出所有 API 域
gitlink-cli schema show repos # 查看 repos 域下的接口
gitlink-cli schema show repos.list # 查看具体接口参数详情
```
从内嵌的 `meta_data.json` 读取,帮助用户和 AI Agent 发现可用 API。
---
## 8 AI Agent Skills 设计
### 8.1 Skills 目录结构
```
skills/
├── gitlink-shared/
│ └── SKILL.md # 认证、全局参数、安全规则、错误处理
├── gitlink-repo/
│ ├── SKILL.md # Shortcuts 总览 + 快速决策
│ └── references/
│ ├── repo-create.md
│ ├── repo-fork.md
│ └── repo-settings.md
├── gitlink-issue/
│ ├── SKILL.md
│ └── references/
│ ├── issue-create.md
│ ├── issue-update.md
│ └── issue-comment.md
├── gitlink-pr/
│ ├── SKILL.md
│ └── references/
│ ├── pr-create.md
│ ├── pr-merge.md
│ └── pr-review.md
├── gitlink-ci/
│ ├── SKILL.md
│ └── references/
│ └── ci-builds.md
├── gitlink-org/
│ └── SKILL.md
├── gitlink-release/
│ └── SKILL.md
├── gitlink-search/
│ └── SKILL.md
├── gitlink-user/
│ └── SKILL.md
├── gitlink-pm/
│ └── SKILL.md
└── gitlink-workflow/
└── SKILL.md # AI 自动化工作流 recipes
```
### 8.2 gitlink-shared/SKILL.md 核心内容
```markdown
# gitlink-cli 共享规则
## 认证
- 首次使用:`gitlink-cli auth login`
- Token 有效期 7 天,过期需重新登录
- 遇到 401/403 错误时,引导用户重新登录
## 上下文解析
- 在 git 仓库目录下自动解析 owner/repo
- 可通过 --owner/--repo 显式指定
## 输出格式
- 默认 table 格式AI 场景建议 --format json
- 所有输出遵循 {ok, data, error, meta} Envelope
## 安全规则
- 禁止输出 Token 到终端明文
- 写入/删除操作前必须确认用户意图
- 使用 --dry-run 预览危险请求
```
### 8.3 gitlink-workflow/SKILL.md — AI 工作流
提供 Claude Code 可直接调用的高级工作流模板:
| 工作流 | 描述 |
|--------|------|
| Issue Triage | 自动分类新 Issuebug/feature/question添加标签 |
| PR Review | 获取 PR diff分析代码质量添加 review 评论 |
| Release Notes | 从 commits 自动生成版本发布说明 |
| Repo Setup | 初始化仓库README、License、.gitignore、分支保护 |
| Sprint Report | 汇总 Issue/PR 统计,生成周报 |
---
## 9 批量操作设计模式
Issue 和 Repo 两个领域均实现了批量操作命令,遵循统一的设计模式。
### 9.1 命令清单
| 领域 | 命令 | 用途 | 输入方式 |
|------|------|------|----------|
| issue | `+batch-close` | 批量关闭 | `--numbers``--from` CSV |
| issue | `+batch-status` | 批量更换状态 | `--state` + `--numbers`/`--from` |
| issue | `+batch-priority` | 批量更换优先级 | `--priority` + `--numbers`/`--from` |
| issue | `+batch-assign` | 批量更换负责人 | `--assignee` + `--numbers`/`--from` |
| issue | `+batch-label` | 批量更换标记 | `--label` + `--numbers`/`--from` |
| issue | `+batch-create` | 批量创建 Issue | `--titles``--from` CSV支持 Bug/Feature 模板) |
| repo | `+batch-create` | 批量创建仓库 | `--names``--from` CSV |
| repo | `+batch-update` | 批量更新仓库 | `--names``--from` CSV |
### 9.2 核心类型
```go
type BatchResult struct {
Number string `json:"number"` // Issue 编号或仓库名
Action string `json:"action"` // 操作类型
Status string `json:"status"` // 执行结果
Error string `json:"error,omitempty"`
}
type BatchSummary struct {
Repository string `json:"repository"`
Action string `json:"action"`
Value string `json:"value,omitempty"`
DryRun bool `json:"dry_run"`
Total int `json:"total"`
Succeeded int `json:"succeeded"`
Failed int `json:"failed"`
Results []BatchResult `json:"results"`
}
```
### 9.3 统一设计原则
| 原则 | 说明 |
|------|------|
| **输入灵活** | `--numbers`/`--names`(内联逗号分隔)和 `--from`CSV 文件)可同时使用,自动去重合并 |
| **dry-run 统一** | 所有批量命令支持 `--dry-run`,预览模式下 status 为 `"planned"`,不发起写请求 |
| **错误不中断** | 单条失败不影响后续处理,全部执行完后返回完整汇总。有任何失败则 exit code = 1 |
| **输出统一** | 所有命令输出相同结构的 `BatchSummary` JSON |
| **修改前先 GET** | Issue 批量修改先 GET 当前 Issue 保留 subject/descriptionPATCH 时只替换目标字段。Repo 批量更新先 GET 获取 name + identifier |
| **参数容错** | 所有名称映射(状态、优先级、标签、负责人)同时支持字符串名和直接传数字 ID |
### 9.4 Issue 参数值映射
**状态**`new`(1) / `in-progress`(2) / `resolved`(3) / `closed`(5) / `rejected`(6)
**优先级**`low`(1) / `normal`(2) / `high`(3) / `urgent`(4)
**标记**:使用项目级中文标签名映射到大整数 ID`缺陷`→315526、`功能`→315527
**负责人**:传入 login 用户名CLI 调用 `/users/{login}` API 转换为 `user_id`
### 9.5 Issue 批量创建模板系统
`+batch-create` 支持三种输入模式:
1. **CLI 直接输入**`--titles`):逗号分隔标题,统一应用 `--priority`/`--label`/`--assignee`/`--state`
2. **自由 CSV**`--from`):自由指定 title/body/priority/label/assignee/status 列
3. **模板 CSV**`--from` + `--template`
- `--template bug`:自动生成 Bug 描述格式,自动设置缺陷标签
- `--template feature`:自动生成功能描述格式,自动设置功能标签
### 9.6 Repo 批量操作注意事项
- **batch-create**POST 路径 `/{login}/{name}` 中的 login 必须是当前登录用户,需先 `GET /users/me`
- **batch-update**PATCH 请求体必须包含从 GET 获取的 `name``identifier`,否则 API 报错
- **--private/--public 互斥**batch-update 不允许同时设置两个标志
### 9.7 关键 API 字段差异
GitLink 基于 Redmine 但修改了大量字段名:
| Redmine 标准字段 | GitLink 实际字段 | 格式 |
|-----------------|-----------------|------|
| `assigned_to_id` | `assigner_ids` | 数组 `[user_id]` |
| `tracker_id` | `issue_tag_ids` | 数组 `[tag_id]`(项目级大整数) |
> GitLink API 对不认识的字段返回 200 而非报错,字段名错误会导致静默失败。必须通过浏览器 DevTools 抓取实际请求确认字段名和格式。
---
## 10 Wiki Shortcut 设计
Wiki 是独立的全新 Shortcut 领域,提供 5 个命令覆盖 Wiki 页面的 CRUD 操作。
### 10.1 双域名架构
Wiki API 部署在 gateway 域名上,与主站 APIwww 域名)分离:
```
┌─ www 域名 ─────────────────────┐
resolveProjectID() → │ GET /{owner}/{repo}/detail.json │ → project_id
└────────────────────────────────┘
┌─ gateway 域名 ───────────────────────────┐
callWikiAPI*() → │ /wiki/open/* (不带 .json) │ → 解包 code/data
└──────────────────────────────────────────┘
```
- **www 域名**`https://www.gitlink.org.cn/api`):用于 detail API 获取 project_id走默认 client
- **gateway 域名**`https://gateway.gitlink.org.cn/api`):用于所有 wiki CRUD API走独立 client
### 10.2 Client 扩展
`internal/client/client.go` 新增 `SkipJSONSuffix` 字段:
```go
type Client struct {
// ... 原有字段 ...
SkipJSONSuffix bool // 为 true 时不自动追加 .json 后缀wiki gateway API 需要)
}
```
wiki 命令创建独立 client 实例,设置 `SkipJSONSuffix: true` 并使用 gateway BaseURL。
### 10.3 响应解包
Gateway API 使用不同的响应格式 `{code, data, msg}`(而非常规的 `{status, ...}`
```go
// unwrapGatewayResponse 解包 gateway 响应
// 成功: code=200/201, 提取 data 字段
// 失败: code=500/400/404, 返回 "[code] msg" 错误信息
func unwrapGatewayResponse(raw []byte) ([]byte, error)
```
### 10.4 命令详情
| 命令 | HTTP 方法 | API 路径 | 关键参数 |
|------|----------|---------|---------|
| `wiki +list` | GET | `/wiki/open/wikiPages` | 无额外参数 |
| `wiki +view` | GET | `/wiki/open/getWiki` | `--title`(必填) |
| `wiki +create` | POST | `/wiki/open/createWiki` | `--title`(必填)`--content/--file` `--message` |
| `wiki +update` | PUT | `/wiki/open/updateWiki` | `--title`(必填)`--cover/--add` `--file` |
| `wiki +delete` | DELETE | `/wiki/open/deleteWiki` | `--title`(必填) |
### 10.5 特殊处理
| 处理项 | 说明 |
|--------|------|
| **base64 编解码** | Wiki 内容在 API 中为 base64 编码CLI 自动编解码,对用户透明 |
| **project_id 缓存** | `resolveProjectID()` 使用 `sync.Map` 缓存,同一 owner/repo 只调一次 API |
| **owner/repo 自动解析** | 在 git 仓库目录下可省略 `--owner`/`--repo` |
| **--update --add 模式** | 先 GET 现有内容 → 解码 → 追加 → 重新编码 → PUT 提交 |
| **嵌套对象过滤** | 表格输出时过滤无意义的嵌套对象字段(如 wiki_clone_link |
### 10.6 已知限制
- **delete 后端 bug**GitLink 平台 `deleteWiki` API 只清空内容,不删除侧边栏条目
- **gateway 域名硬编码**wiki API 仅部署在 gatewaydetail API 在 www不可互换
- **create/update pageName 差异**create 接受原始中文 pageNameupdate 需要 URL 编码
---
## 11 完整命令参考
```
gitlink-cli
├── auth
│ ├── login # 登录
│ ├── logout # 登出
│ └── status # 认证状态
├── config
│ ├── init # 初始化配置
│ ├── set # 设置配置项
│ ├── get # 读取配置项
│ └── list # 列出所有配置
├── repo
│ ├── +create # 创建仓库
│ ├── +clone # 克隆仓库
│ ├── +fork # Fork 仓库
│ ├── +list # 仓库列表
│ ├── +info # 仓库详情
│ ├── +delete # 删除仓库
│ ├── +settings # 仓库设置
│ ├── +batch-create # 批量创建仓库
│ └── +batch-update # 批量更新仓库
├── issue
│ ├── +list # Issue 列表
│ ├── +create # 创建 Issue
│ ├── +view # Issue 详情
│ ├── +update # 更新 Issue
│ ├── +close # 关闭 Issue
│ ├── +comment # 添加评论
│ ├── +assign # 指派
│ ├── +label # 标签管理
│ ├── +batch-close # 批量关闭 Issue
│ ├── +batch-status # 批量更换状态
│ ├── +batch-priority # 批量更换优先级
│ ├── +batch-assign # 批量更换负责人
│ ├── +batch-label # 批量更换标记
│ └── +batch-create # 批量创建 Issue含 Bug/Feature 模板)
├── pr
│ ├── +list # PR 列表
│ ├── +create # 创建 PR
│ ├── +view # PR 详情
│ ├── +merge # 合并 PR
│ ├── +close # 关闭 PR
│ ├── +review # 代码审查
│ ├── +files # 变更文件
│ └── +diff # 查看 Diff
├── release
│ ├── +list # 发布列表
│ ├── +create # 创建发布
│ ├── +view # 发布详情
│ ├── +delete # 删除发布
│ └── +download # 下载附件
├── branch
│ ├── +list # 分支列表
│ ├── +create # 创建分支
│ ├── +delete # 删除分支
│ ├── +protect # 设置保护
│ └── +unprotect # 取消保护
├── org
│ ├── +list # 组织列表
│ ├── +info # 组织详情
│ ├── +members # 成员列表
│ └── +create # 创建组织
├── ci
│ ├── +builds # 构建列表
│ ├── +logs # 构建日志
│ ├── +restart # 重启构建
│ └── +stop # 停止构建
├── user
│ ├── +me # 当前用户
│ └── +info # 用户详情
├── webhook
│ ├── +list # Webhook 列表
│ ├── +create # 创建 Webhook
│ ├── +update # 更新 Webhook
│ ├── +delete # 删除 Webhook
│ ├── +test # 测试 Webhook
│ └── +info # Webhook 详情
├── wiki
│ ├── +list # Wiki 页面列表
│ ├── +view # 查看 Wiki 页面
│ ├── +create # 创建 Wiki 页面
│ ├── +update # 更新 Wiki 页面
│ └── +delete # 删除 Wiki 页面
├── search
│ ├── +repos # 搜索仓库
│ ├── +issues # 搜索 Issue
│ └── +users # 搜索用户
├── schema
│ ├── list # API 域列表
│ └── show # 接口详情
├── api
│ ├── GET # 原始 GET
│ ├── POST # 原始 POST
│ ├── PUT # 原始 PUT
│ └── DELETE # 原始 DELETE
└── version # 版本信息
```
---
## 12 关键文件清单
实现时需要修改/创建的核心文件:
| 文件 | 说明 |
|------|------|
| `cmd/root.go` | 根命令、全局 flags--owner, --repo, --format, --debug |
| `cmd/auth/*.go` | login / logout / status |
| `cmd/api/api.go` | Raw API 层 |
| `cmd/service/service.go` | 元数据驱动命令生成 |
| `internal/auth/login.go` | 用户名密码登录逻辑 |
| `internal/auth/token_store.go` | Keychain 存储 |
| `internal/auth/transport.go` | Bearer Token 注入 |
| `internal/client/client.go` | HTTP 客户端 + 错误解包 |
| `internal/client/pagination.go` | 分页迭代器 |
| `internal/config/config.go` | 配置文件读写 |
| `internal/context/repo.go` | git remote 解析 |
| `internal/output/envelope.go` | Envelope 输出 |
| `internal/output/formatter.go` | table / json / yaml 格式化 |
| `internal/registry/loader.go` | 元数据加载 |
| `internal/registry/meta_data.json` | API 元数据 |
| `shortcuts/common/types.go` | Shortcut 核心类型 |
| `shortcuts/common/runner.go` | RuntimeContext |
| `shortcuts/repo/*.go` | 仓库 shortcuts含 batch_create/batch_update |
| `shortcuts/issue/*.go` | Issue shortcuts含 batch.go + batch_create.go 批量操作) |
| `shortcuts/wiki/*.go` | Wiki shortcutslist, view, create, update, delete |
| `shortcuts/webhook/*.go` | Webhook shortcutslist, create, update, delete, test, info |
| `shortcuts/pr/*.go` | PR shortcuts |
| `shortcuts/register.go` | Shortcut 注册 |
| `skills/gitlink-shared/SKILL.md` | 共享 Skill |
| `skills/gitlink-*/SKILL.md` | 各领域 Skill |
---
## 13 开发计划
### Phase 1: Foundation第 1-2 周)
- 项目骨架go mod init, Makefile, cobra root
- `internal/config` — 配置管理
- `internal/auth` — 登录 + Keychain + Transport
- `internal/client` — HTTP 客户端 + 错误解包
- `internal/output` — Envelope + Formatter
- `cmd/auth` — login / logout / status
- `cmd/config` — init / set / get / list
**验证**`gitlink-cli auth login` → `gitlink-cli api GET /api/users/me` 返回当前用户
### Phase 2: Framework第 3-4 周)
- `internal/context/repo.go` — git remote 解析
- `internal/client/pagination.go` — 分页迭代器
- `shortcuts/common/` — Shortcut 框架 + RuntimeContext
- `cmd/api/` — Raw API 层
- `internal/registry/` — 元数据加载 + `cmd/service/`
- `cmd/schema/` — Schema 自省
**验证**`gitlink-cli api GET /api/projects` + `gitlink-cli schema list`
### Phase 3: Core Shortcuts第 5-7 周)
按优先级实现 shortcuts
1. `user +me` / `user +info`
2. `repo +list` / `+info` / `+create` / `+fork` / `+clone`
3. `issue +list` / `+create` / `+view` / `+close` / `+comment`
4. `pr +list` / `+create` / `+view` / `+merge` / `+review`
5. `branch +list` / `+protect`
6. `release +list` / `+create`
7. `org +list` / `+info` / `+members`
8. `ci +builds` / `+logs`
9. `search +repos` / `+issues`
**验证**:完整 CRUD 工作流测试
### Phase 4: AI Skills第 8-9 周)
- 编写 11 个 SKILL.md 文件
- 每个 Skill 包含:命令参考、参数说明、返回值、使用示例、错误处理
- 编写 workflow recipesIssue Triage, PR Review, Release Notes
- Claude Code 集成测试
**验证**Claude Code 使用 Skills 自动完成 Issue 创建 → PR 创建 → 合并全流程
### Phase 5: Polish & Release第 10-11 周)
- 补充单元测试和集成测试
- 完善 README 和用户文档
- goreleaser 配置,多平台构建
- Homebrew / APT / Scoop 包分发
- 发布 v0.1.0
---
## 14 验证方案
| 阶段 | 验证方式 |
|------|----------|
| Phase 1 | `gitlink-cli auth login` + `gitlink-cli api GET /api/users/me` |
| Phase 2 | `gitlink-cli api GET /api/projects` + `gitlink-cli schema list` |
| Phase 3 | 端到端:创建仓库 → 创建 Issue → 创建 PR → 合并 → 发布 Release |
| Phase 4 | Claude Code Skills 集成测试AI 自动完成 Issue/PR 工作流 |
| Phase 5 | `goreleaser --snapshot` 多平台构建 + 安装脚本测试 |