gitlink-cli/doc/wiki-implementation.md

415 lines
14 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.

# Wiki Shortcuts 实现文档
> 作者:人员 A | 日期2026-06-04
## 一、功能概述
为 GitLink CLI 新增了 **Wiki 管理** 功能模块,共 **9 个** Shortcut 命令,覆盖 Wiki 页面和目录的完整管理操作。
### 命令列表
| 命令 | 说明 | 方法 | 真实 API 验证 |
|------|------|------|--------------|
| `wiki +list` | 列出所有 Wiki 页面 | GET | ✅ |
| `wiki +view` | 查看 Wiki 页面内容 | GET | ✅ |
| `wiki +create` | 创建 Wiki 页面(可指定目录) | POST | ✅ |
| `wiki +update` | 更新 Wiki 页面内容 | PUT | ✅ |
| `wiki +delete` | 删除 Wiki 页面 + 清理 Sidebar | DELETE | ✅ |
| `wiki +mkdir` | 新建目录(可建子目录) | PUT (Sidebar) | ✅ |
| `wiki +rmdir` | 删除目录 | PUT (Sidebar) | ✅ |
| `wiki +rename` | 重命名页面 | GET+POST+DELETE+PUT | ✅ |
| `wiki +renamedir` | 重命名目录 | PUT (Sidebar) | ✅ |
### 参数说明
| 参数 | 短选项 | 说明 | 必填 | 适用命令 |
|------|--------|------|------|----------|
| `--owner` | | 仓库拥有者 | 是* | 所有 |
| `--repo` | | 仓库名称 | 是* | 所有 |
| `--name` | `-n` | 页面/目录名称 | 是 | view, create, update, delete, mkdir, rmdir, rename, renamedir |
| `--content` | `-c` | 页面内容(自动 base64 编码) | 是 | create, update |
| `--message` | `-m` | 提交信息 | 否 | create, update |
| `--dir` | `-d` | 父目录名(将页面创建到该目录下) | 否 | create |
| `--parent` | `-p` | 父目录名(创建子目录) | 否 | mkdir |
| `--new-name` | `-N` | 新名称 | 是 | rename, renamedir |
> *在 git 仓库目录下执行时,`--owner` 和 `--repo` 会自动从 git remote 解析。
---
## 二、技术架构
### API 网关差异
Wiki API 与其他 Shortcut 使用的标准 API 路径完全不同:
| 类型 | 域名 | 路径前缀 | 格式 |
|------|------|----------|------|
| 标准 API | `www.gitlink.org.cn/api` | `/v1/{owner}/{repo}/...` | URL 带 `.json` 后缀,参数用 query |
| **Wiki API** | `gateway.gitlink.org.cn/api` | `/wiki/open/...` | URL 无后缀,参数用 JSON body 或 query |
### 关键发现Wiki API 真实地址
GitLink 官方 API 文档Swagger中**没有记录** Wiki 相关接口。真实的 Wiki API 地址是通过浏览器 F12 抓包发现的:
> 在浏览器中打开 GitLink 项目的 Wiki 页面,按 F12 打开开发者工具 → Network 标签 → 筛选 Fetch/XHR 请求 → 观察 Wiki 操作发出的网络请求。
发现 Wiki API 位于 `gateway.gitlink.org.cn/api/wiki/open/` 路径下,而非文档中的 `www.gitlink.org.cn/api/wiki/`
### Sidebar 目录机制
GitLink Wiki 的目录结构**完全由 `_Sidebar` 页面控制**,没有单独的目录 API。Sidebar 内容格式:
```
- 目录A
[[页面1]]
- 子目录
[[页面2]]
[[独立页面]]
- 目录B
[[页面3]]
```
规则:
- `- 目录名` = 目录条目
- `[[页面名]]` = 页面链接
- `Tab` 缩进 = 层级嵌套
因此目录操作(新建/删除/重命名)的本质都是**读取 → 修改 → 更新 Sidebar 内容**。
### `callWikiAPI` 机制
由于 Wiki API 使用不同的网关域名,代码中实现了 `callWikiAPI` 辅助函数来临时切换 API 基地址:
```go
const wikiBaseURL = "https://gateway.gitlink.org.cn/api"
func callWikiAPI(ctx *common.RuntimeContext, method, path string, body interface{}, query url.Values) error {
origBase := ctx.Client.BaseURL
if !strings.HasPrefix(origBase, "http://127.0.0.1") {
ctx.Client.BaseURL = wikiBaseURL
}
defer func() { ctx.Client.BaseURL = origBase }()
// ... 执行 API 请求
}
```
### `fetchProjectID` 机制
Wiki API 需要 `projectId` 参数,而 CLI 输入只有 `owner/repo`。通过先调用标准 API 获取仓库信息,从中提取 `project_id`
```
1. GET /whale_hihihi/gitlink-cli.json → 获取 project_id: 1546648
2. GET /wiki/open/wikiPages?projectId=1546648&... → 获取 Wiki 页面列表
```
优先级:`project_id` > `repo_id` > `id`
> **注意:** `project_id` 和 `repo_id` 是不同的值。Wiki API 必须使用 `project_id`。
### 请求流程示例
**`wiki +list`**
```
GET www.gitlink.org.cn/api/whale_hihihi/gitlink-cli.json → project_id
GET gateway.gitlink.org.cn/api/wiki/open/wikiPages?projectId=... → 页面列表
```
**`wiki +delete`(两步操作):**
```
GET www.gitlink.org.cn/api/.../gitlink-cli.json → project_id
DELETE gateway.gitlink.org.cn/api/wiki/open/deleteWiki → 清空页面内容
(sleep 2s)
GET gateway.gitlink.org.cn/api/wiki/open/getWiki?pageName=_Sidebar → 读取 Sidebar
PUT gateway.gitlink.org.cn/api/wiki/open/updateWiki → 更新 Sidebar移除 [[pageName]]
```
**`wiki +rename`(四步操作):**
```
GET .../getWiki?pageName=oldName → 获取旧页面内容
POST .../createWiki → 创建新页面(复用旧内容)
DELETE .../deleteWiki → 删除旧页面
PUT .../updateWiki (_Sidebar) → [[oldName]] 替换为 [[newName]]
```
---
## 三、涉及文件
| 文件 | 操作 | 说明 |
|------|------|------|
| `shortcuts/wiki/wiki.go` | 新增 | Wiki 9 个命令的实现 + Sidebar 操作辅助函数 |
| `shortcuts/wiki/wiki_test.go` | 新增 | 单元测试 |
| `shortcuts/register.go` | 修改 | 注册 wiki 模块 |
| `skills/gitlink-wiki/SKILL.md` | 新增 | Skill 文档 |
| `internal/client/client.go` | 已有 | `DoRaw` 方法(无需 `.json` 后缀的 API 调用) |
---
## 四、使用方法
### 列出 Wiki 页面
```bash
`./gitlink-cli.exe wiki +list --owner whale_hihihi --repo test
```
返回示例:
```json
{
"ok": true,
"data": {
"code": 200,
"data": [
{"sub_url": "_Sidebar", "title": "_Sidebar"},
{"sub_url": "test", "title": "test"}
],
"msg": "操作成功"
}
}
```
> `_Sidebar` 是 Wiki 系统自动生成的侧边栏导航页面,非手动创建。
### 查看 Wiki 页面
```bash
`./gitlink-cli.exe wiki +view --owner whale_hihihi --repo test --name test
```
返回内容中 `content_base64` 字段为 base64 编码的页面内容(如 `MTIz` 解码后为 `123`)。
### 创建 Wiki 页面
```bash
# 在根目录创建页面
`./gitlink-cli.exe wiki +create --owner whale_hihihi --repo test \
--name CLITest --content "Hello from CLI" --message "test create"
# 在指定目录下创建页面
`./gitlink-cli.exe wiki +create --owner whale_hihihi --repo test \
--name dirpage --content "page in dir" --dir mydir
```
成功后返回 `code: 201` 及新页面的提交信息sha、author、date
### 更新 Wiki 页面
```bash
`./gitlink-cli.exe wiki +update --owner whale_hihihi --repo test \
--name test --content "Updated content" --message "test update"
```
`--message` 可选,是 Git 提交信息。
### 删除 Wiki 页面
```bash
`./gitlink-cli.exe wiki +delete --owner whale_hihihi --repo test --name test
```
内部执行两步操作:清空页面内容 → 清理 Sidebar 中的页面链接。
### 新建目录
```bash
# 新建顶级目录
`./gitlink-cli.exe wiki +mkdir --owner whale_hihihi --repo test --name mydir
# 在指定目录下新建子目录
`./gitlink-cli.exe wiki +mkdir --owner whale_hihihi --repo test --name subdir --parent mydir
```
本质是更新 `_Sidebar` 内容,添加 `- 目录名` 条目。
### 删除目录
```bash
`./gitlink-cli.exe wiki +rmdir --owner whale_hihihi --repo test --name mydir
```
从 Sidebar 中移除 `- 目录名` 及其所有子项(子目录和页面链接)。**注意:不会删除目录下的实际 Wiki 页面,只移除 Sidebar 导航。**
### 重命名页面
```bash
`./gitlink-cli.exe wiki +rename --owner whale_hihihi --repo test \
--name oldpage --new-name newpage
```
内部执行四步操作:获取旧页面内容 → 创建新页面 → 删除旧页面 → 更新 Sidebar 链接。
### 重命名目录
```bash
`./gitlink-cli.exe wiki +renamedir --owner whale_hihihi --repo test \
--name olddir --new-name newdir
```
在 Sidebar 中将 `- olddir` 替换为 `- newdir`
---
## 五、测试方法
### 5.1 单元测试
```bash
go test -v ./shortcuts/wiki/
```
测试用例:
| 测试 | 验证内容 |
|------|----------|
| `TestWikiList` | GET 请求发送到 `/wiki/open/wikiPages`,返回页面列表 |
| `TestWikiView` | GET 请求包含 `pageName` query 参数 |
| `TestWikiCreate` | POST 请求 body 包含 `pageName`、`content_base64`、`owner`、`repo` |
| `TestWikiUpdate` | PUT 请求 body 包含 `pageName`、`message` 等字段 |
| `TestWikiDelete` | DELETE + GET Sidebar + PUT 更新 Sidebar验证三步操作 |
单元测试使用 `httptest` mock 服务器,不会请求真实 API。由于 `callWikiAPI` 检测到 `http://127.0.0.1` 前缀时跳过 BaseURL 切换mock 测试可以正常运行。
### 5.2 真实 API 验证
```bash
# 构建
go build -o gitlink-cli.exe .
# 需要 token 认证
$env:GITLINK_TOKEN="<your_token>"
# 页面操作
./gitlink-cli.exe wiki +list --owner whale_hihihi --repo test
./gitlink-cli.exe wiki +view --owner whale_hihihi --repo test --name test
./gitlink-cli.exe wiki +create --owner whale_hihihi --repo test --name CLITest --content "Hello"
./gitlink-cli.exe wiki +update --owner whale_hihihi --repo test --name CLITest --content "Updated"
./gitlink-cli.exe wiki +delete --owner whale_hihihi --repo test --name CLITest
# 目录操作
./gitlink-cli.exe wiki +mkdir --owner whale_hihihi --repo test --name testdir
./gitlink-cli.exe wiki +mkdir --owner whale_hihihi --repo test --name subdir --parent testdir
./gitlink-cli.exe wiki +create --owner whale_hihihi --repo test --name dp1 --content "dir page" --dir testdir
./gitlink-cli.exe wiki +renamedir --owner whale_hihihi --repo test --name testdir --new-name mydir
./gitlink-cli.exe wiki +rename --owner whale_hihihi --repo test --name dp1 --new-name dp1_renamed
./gitlink-cli.exe wiki +rmdir --owner whale_hihihi --repo test --name mydir
```
使用 `--debug` 参数可以看到实际请求的 URL 和 body。
---
## 六、已知问题与设计说明
### 6.1 Wiki API 未记录在官方文档中
GitLink Swagger API 文档中没有 Wiki 相关接口。所有 Wiki API 端点均通过浏览器 F12 抓包发现。
### 6.2 `+delete` 的两步删除机制
GitLink 的 `deleteWiki` API **只清空页面内容,不删除页面条目**。页面条目保存在 `_Sidebar` 中。因此 `+delete` 命令采用两步操作:
1. 调用 `DELETE /wiki/open/deleteWiki`:清空页面内容
2. 等待 2 秒后更新 `_Sidebar`:移除 `[[pageName]]` 链接
### 6.3 `_Sidebar` 系统页面
Wiki 页面列表中始终包含一个 `_Sidebar` 页面,这是 GitLink Wiki 系统自动生成的侧边栏配置页面。所有目录操作都通过修改此页面实现。
### 6.4 `+rmdir` 只移除导航,不删除页面
`+rmdir` 从 Sidebar 中移除目录及其子项的导航链接,但**不会删除目录下的实际 Wiki 页面文件**。这是 GitLink 的设计限制——目录只是 Sidebar 的组织结构,不是真正的文件系统目录。
---
## 七、API 端点参考
| 端点 | 方法 | 参数 | 说明 |
|------|------|------|------|
| `/wiki/open/wikiPages` | GET | query: `owner`, `repo`, `projectId` | 获取页面列表 |
| `/wiki/open/getWiki` | GET | query: `owner`, `repo`, `projectId`, `pageName` | 获取页面内容 |
| `/wiki/open/createWiki` | POST | body: `owner`, `repo`, `projectId`, `pageName`, `title`, `content_base64`, `message` | 创建页面 |
| `/wiki/open/updateWiki` | PUT | body: `owner`, `repo`, `projectId`, `pageName`, `title`, `content_base64`, `message` | 更新页面(含 Sidebar |
| `/wiki/open/deleteWiki` | DELETE | body: `owner`, `repo`, `projectId`, `pageName` | 删除页面(仅清空内容) |
所有端点的 base URL`https://gateway.gitlink.org.cn/api`
> **注:** 目录操作mkdir/rmdir/renamedir没有独立的 API 端点,均通过 `updateWiki` 修改 `_Sidebar` 页面内容实现。
---
## 八、Webhook 增强
### 8.1 概述
在 Webhook 领域原有 3 个命令list、create、delete的基础上新增了 4 个命令,补全了 Webhook 管理的完整生命周期。
### 8.2 命令对比
| 原有命令 | 说明 | 新增命令 | 说明 |
|----------|------|----------|------|
| `webhook +list` | 列出 Webhook | **`webhook +view`** | 查看 Webhook 详情URL、事件、密钥等 |
| `webhook +create` | 创建 Webhook | **`webhook +update`** | 更新 Webhook 配置URL、事件、密钥等 |
| `webhook +delete` | 删除 Webhook | **`webhook +history`** | 查看 Webhook 推送历史(每次推送的状态和响应) |
| | | **`webhook +test`** | 触发一次测试推送(验证 Webhook 是否正常工作) |
### 8.3 使用示例
```bash
# 列出所有 Webhook
`./gitlink-cli.exe webhook +list --owner whale_hihihi --repo test
# 创建 Webhook
`./gitlink-cli.exe webhook +create --owner whale_hihihi --repo test \
--url https://example.com/hook --events push --secret mysecret
# 查看 Webhook 详情
`./gitlink-cli.exe webhook +view --owner whale_hihihi --repo test --id 51347
# 更新 Webhook 事件列表
`./gitlink-cli.exe webhook +update --owner whale_hihihi --repo test \
--id 51347 --events push,issues_only,pull_request_only
# 查看推送历史
`./gitlink-cli.exe webhook +history --owner whale_hihihi --repo test --id 51347
# 测试推送
`./gitlink-cli.exe webhook +test --owner whale_hihihi --repo test --id 51347
# 删除 Webhook
`./gitlink-cli.exe webhook +delete --owner whale_hihihi --repo test --id 51347
```
### 8.4 涉及文件
| 文件 | 说明 |
|------|------|
| `shortcuts/webhook/webhook.go` | 新增 view、update、tasks、test 4 个 Shortcut |
| `shortcuts/webhook/webhook_test.go` | 新增 4 个单元测试 |
### 8.5 API 端点参考
| 端点 | 方法 | 说明 | 状态 |
|------|------|------|------|
| `/v1/{owner}/{repo}/webhooks` | GET | 列出 Webhook | 原有 |
| `/v1/{owner}/{repo}/webhooks` | POST | 创建 Webhook | 原有 |
| `/v1/{owner}/{repo}/webhooks/{id}` | DELETE | 删除 Webhook | 原有 |
| `/v1/{owner}/{repo}/webhooks/{id}` | GET | 查看 Webhook 详情 | **新增** |
| `/v1/{owner}/{repo}/webhooks/{id}` | PUT | 更新 Webhook | **新增** |
| `/v1/{owner}/{repo}/webhooks/{id}/hooktasks` | GET | 推送历史 | **新增** |
| `/v1/{owner}/{repo}/webhooks/{id}/tests` | POST | 测试推送 | **新增** |
### 8.6 真实 API 验证
全部 7 个命令在 `whale_hihihi/gitlink-cli` 项目上验证通过:
| 命令 | 验证结果 |
|------|----------|
| `+list` | ✅ 返回 2 个 webhook |
| `+create` | ✅ 创建成功,返回 id |
| `+view` | ✅ 返回完整 webhook 配置 |
| `+update` | ✅ 事件列表更新成功 |
| `+tasks` | ✅ 返回推送历史列表 |
| `+test` | ✅ 测试推送成功 |
| `+delete` | ✅ 删除成功 |