# 01 - 架构 ## 总体数据流 ``` ┌─────────────┐ ┌────────────┐ │ 开发者 │ ① @claude 在 issue/PR 评论提需求 │ Gitea │ │ (浏览器) │ ───────────────────────────────────────▶│ (3000) │ └─────────────┘ └─────┬──────┘ │ ② webhook → workflow_dispatch ▼ ┌───────────────┐ │ act_runner │ │ (本机容器) │ └─────┬─────────┘ │ ③ 启动 Action ▼ ┌────────────────────────────────────┐ │ claude-gitea-agent Action │ │ ┌──────────────────────────────┐ │ │ │ 1. parse trigger │ │ │ │ 2. fetch issue/PR context │ │ │ │ 3. build prompt + skills │ │ │ │ 4. exec `claude` CLI │ │ │ │ 5. post comment / open PR │ │ │ └──────────────────────────────┘ │ └──────┬─────────────────────────────┘ │ ④ Gitea API (评论/分支/PR) ▼ ┌────────────┐ │ Gitea │ ⑤ 用户在评论里看到 Claude 回复 └────────────┘ ``` ## 关键组件 ### 1. 触发器(trigger) | 入口 | 上游 | Gitea 对应 | |---|---|---| | `issue_comment` | `github.event.comment.body` | `gitea.event.comment.body` ✅ 一致 | | `issues` (opened/edited) | 一致 | 一致 | | `pull_request_review_comment` | 一致 | 一致 | | `workflow_dispatch` | 手动触发 | 一致 | 触发短语:`@claude` 在评论/issue 正文里出现。 ### 2. Gitea API 适配层(src/gitea/) **对应上游 `src/github/` 的 1:1 重写**: | 上游模块 | Gitea 移植 | 改造点 | |---|---|---| | `github/api/` | `gitea/api/` | 用 Gitea Swagger SDK 或 fetch;endpoint 90% 相似 | | `github/data/` | `gitea/data/` | 数据 schema 重写(少量字段差异) | | `github/operations/` | `gitea/operations/` | 评论 / branch / PR 创建逻辑 | | `github/validation/` | `gitea/validation/` | webhook 签名校验、权限检查 | | `github/utils/` | `gitea/utils/` | 工具函数 | ### 3. 提示词层(src/create-prompt/) **几乎不动**。生成给 Claude 的初始 prompt(包含 issue 标题/正文、相关代码、历史评论)。 ### 4. 模式层(src/modes/) - `tag` 模式:被 @claude 提到时响应(**主用**) - `agent` 模式:显式 prompt 启动(高级用法,后期支持) **几乎不动**。 ### 5. Claude 执行层 调用本机 `claude` CLI 或 `@anthropic-ai/claude-agent-sdk`。携带: - `CLAUDE_AGENT_SDK_AUTH`:用户的 API key(Gitea Secret) - `--add-dir`:仓库 checkout 后的工作目录 - `--allowed-tools`:默认 Read/Edit/Write/Bash,可通过 inputs 限制 ## Gitea Actions 兼容性预判 | 上游依赖 | Gitea Actions 表现 | 处理 | |---|---|---| | `@actions/core` | ✅ 完全兼容 | 原样用 | | `@actions/github` | ❌ 调用 GitHub API | 替换为 Gitea API | | `@octokit/rest` | ❌ GitHub-only | 替换为 Gitea SDK 或 fetch | | `@octokit/graphql` | ❌ Gitea 暂无 GraphQL | 改写为 REST 拼接 | | `@octokit/webhooks-types` | 类型定义 | 自己写 Gitea 的 types | | `@modelcontextprotocol/sdk` | ✅ 与平台无关 | 原样用 | | `@anthropic-ai/claude-agent-sdk` | ✅ 与平台无关 | 原样用 | | `actions/checkout@v4` | ✅ Gitea Actions 兼容 | 原样用 | ## 关键路径估算(路线 A) | 阶段 | 工作量 | 关键风险 | |---|---|---| | 搭基础(types/auth/api 骨架) | 2-3 天 | Gitea SDK 选型 | | 端口 issue 评论 + PR 评论场景 | 3-4 天 | webhook payload 字段差异 | | 端口 branch 创建 + PR 提交 | 2-3 天 | Gitea PR API 偶尔有差异 | | 跑通 end-to-end demo | 1-2 天 | act_runner Docker socket 权限 | | 文档 + 自部署指南 | 1 天 | - | | **合计** | **~2 周** | | ## 升级到路线 B 的接口 设计时**保留这两个边界**便于以后切到长驻服务: 1. `EventDispatcher` 接口:当前实现读 `GITEA_EVENT_PATH` 文件;未来实现订阅 webhook 2. `SessionStore` 接口:当前每次 Action run 都重新 build prompt;未来用同一个 Claude session 持续追加消息 具体见 [02-roadmap.md](02-roadmap.md)。