48 lines
3.0 KiB
Markdown
48 lines
3.0 KiB
Markdown
# Gitea Workflow 研究与决策
|
||
|
||
## 需求
|
||
|
||
- Gitea 实例级 Webhook 指向 cc-web;用户在 Issue/PR 普通评论中 `@ccweb-bot`。
|
||
- 未登记仓库首次合法触发自动接入,clone 到可配置工作区根目录。
|
||
- 同一仓库串行、不同仓库并行;任务队列、会话映射和回执状态必须持久化。
|
||
- 所有后台会话固定使用 Codex App 与 yolo;Gitea 是唯一主交互入口。
|
||
- Agent 通过官方 `gitea-mcp` 读取上下文、研究、修改和回帖;cc-web 负责状态与最终兜底。
|
||
|
||
## 本地代码发现
|
||
|
||
- `server.js` 已有持久会话创建、`handleMessage`、Codex App 线程、MCP 配置和 turn 完成路径。
|
||
- `codexAppThreadConfig()` 已将运行时 MCP 组装成 `thread/start.config`;可扩展为工作流专属 `gitea` 配置。
|
||
- `handleCodexAppTurnComplete()` 是最合适的 turn 完成监听点。
|
||
- `handleInternalMcpApi()` 是 cc-web 内部 MCP API,不应暴露为 Gitea 公网 Webhook。
|
||
- 项目无 Node SQLite 依赖;现有会话和配置以 JSON 文件持久化,工作流状态可采用原子 JSON 文件或新增独立存储模块。
|
||
|
||
## 官方 gitea-mcp
|
||
|
||
- 官方仓库:`https://gitea.com/gitea/gitea-mcp`。
|
||
- 支持本机 stdio 与 HTTP;本任务选择 stdio。
|
||
- 支持 `GITEA_HOST`、`GITEA_ACCESS_TOKEN`,可通过 `-t stdio -H <host>` 启动。
|
||
- 工具覆盖 Issue、PR、仓库、文件、分支、提交、Release、Actions 等。
|
||
- 支持 scope/tool 过滤,但用户要求 MVP 开放全部写权限;必须配套暂停、中止和审计。
|
||
|
||
## 外部方案
|
||
|
||
- Matea:最接近完整 Gitea Webhook Agent 网关,可参考其签名、去重、队列和状态机;社区规模仍小。
|
||
- wshm:支持多 Forge 和后台同步,但不是 cc-web 会话桥接。
|
||
- pi-dispatch:队列、预算和沙箱值得参考,但使用 pi Agent。
|
||
- gitea-claude-agent:验证 `@机器人 → 多轮澄清 → PR` 交互,但依赖 Gitea Actions。
|
||
|
||
## 关键技术约束
|
||
|
||
- Webhook 必须在验签、delivery 去重、Bot 自评论过滤后才创建任务。
|
||
- 每个 turn 生成唯一标识,正常最终评论由 MCP 发送;Webhook/API 查询确认真实回帖。
|
||
- 任务完成但没有回帖时,只允许在同一会话发起一次“只补发回执、不重复修改”的隐藏 turn。
|
||
- 回执仍失败才使用 Bot Token 走 Gitea REST 兜底。
|
||
- 共享工作区有未提交修改时不 reset、不覆盖;当前会话可继续,其他会话排队。
|
||
|
||
## 已落地实现
|
||
|
||
- 主服务入口为 `lib/gitea-workflow-service.js`,底层组合 `domain/store/queue`;避免同时维护两套运行时状态。
|
||
- `server.js` 只负责实例化配置、Webhook 路由、工作区 runner、Codex App turn 桥接和管理 API。
|
||
- 管理配置中的 Secret/Token 保存到独立 0600 文件,GET 配置只返回“是否已配置”;保存后重启使运行时闭环读取新凭据。
|
||
- 回帖核验只接受 `kind=final|fallback` 的隐藏标识,状态评论不会误判为最终回帖;查询异常也只进行一次“只补发回执”补偿。
|