# 02 - 路线图 ## 调研结论(2026-05-25) 调研了 4 个候选 OSS: | 项目 | Stars | 契合度 | 结论 | |---|---|---|---| | anthropics/claude-code-action | 7.7k | ⭐⭐⭐⭐⭐ | **GitHub Only**,移植到 Gitea 是这次项目的核心工作 | | All-Hands-AI/OpenHands | 40k+ | ⭐⭐⭐ | 非 Claude 原生,Gitea 支持弱,引入了大量不需要的东西 | | SWE-agent/SWE-agent | 19.3k | ⭐⭐ | 学术为主,一次性自动修,不擅长多轮交互 | | Turrain/claude-gitea-app | 1 | ⭐⭐⭐ | 名字对路但太小(20KB),不能依赖 | **Gitea 生态周边可复用**: - [Sqcows/forgejo-mcp](https://github.com/Sqcows/forgejo-mcp) — Forgejo/Gitea MCP server,103 工具 - [pkulik0/gitea-skill](https://github.com/pkulik0/gitea-skill) — `tea` CLI 的 Claude Code Skill **结论**:复刻 `claude-code-action` 是最直接的路径,OpenHands 等通用方案在交互性上不及。 --- ## 路线 A:移植 `claude-code-action` 到 Gitea Actions(当前阶段) **目标**:端到端跑通最小可用版本,体感先达到 "issue 里说话 → Claude 在评论里回复 → 同意后 PR 自动开"。 ### Milestone A1:基础设施(第 1 周) - [ ] fork upstream,确定 TS/Bun 工具链能在 act_runner 里跑 - [ ] 在 Gitea 控制面板创建 `@claude` bot 用户 + 对应 access token - [ ] 验证 Gitea webhook → workflow_dispatch 链路 - [ ] 写 Gitea API 客户端(`src/gitea/api/`),覆盖: - 评论 CRUD - issue/PR 读取 - 分支创建 + push - PR 创建 ### Milestone A2:tag 模式跑通(第 2 周) - [ ] 移植 `src/modes/tag/`(@claude 触发的最常用模式) - [ ] 移植 `src/create-prompt/`(基本不动,确认 context 字段映射) - [ ] 移植 `src/entrypoints/`(适配 Gitea 事件载荷格式) - [ ] `.gitea/workflows/claude.yml` 示例工作流 - [ ] 在本仓库自己开 issue 验证"对话+提 PR"流程 ### 验收标准 ``` 1. 我在某个 Gitea 仓库开 issue:「加一个返回当前时间的 /now 接口」 2. issue 正文末尾 @claude 3. 1 分钟内出现 Claude 评论:「先确认几点... a/b/c」 4. 我回复评论:「a 这样,b 那样」 5. Claude 再回复对齐 + 开始执行 6. Claude push 分支 + 开 PR,PR 描述里贴着完整对话和实现说明 ``` --- ## 路线 B:长驻 webhook 服务(未来) **触发条件**:路线 A 跑通后,发现每轮交互 30s+ 冷启动太难受,再启动 B。 ### 架构差异 ``` 路线 A:每次评论 → 启动 Action → 加载 context → 退出 (冷) 路线 B:每次评论 → POST 到长驻服务 → 复用 Claude session → 立刻回复 (热) ``` ### 主要工作 - 用 Python 或 Node 写一个常驻 webhook server(FastAPI / Hono) - 用 `@anthropic-ai/claude-agent-sdk` 维护 `{issue_id: ClaudeSession}` 字典 - 每条 Gitea 评论 webhook → 找到对应 session → `session.send_message()` → 回写评论 - 长会话超时回收策略(24h 不活跃释放) - 加载 superpowers skills([skills 目录注入](https://docs.claude.com/api/agent-sdk)) - 部署:和 Gitea 同机 docker-compose,加一个 `claude-agent` 服务 ### 升级路径 设计路线 A 代码时已保留两个抽象接口: ```typescript interface EventDispatcher { // A: read GITEA_EVENT_PATH file // B: subscribe to webhook stream next(): Promise } interface SessionStore { // A: fresh prompt each run // B: persistent ClaudeSession per issue get(key: string): Promise save(key: string, session: Session): Promise } ``` 切换路线时只需新实现这两个接口,核心业务逻辑(trigger 解析、Gitea API、PR 流程)不动。 --- ## 不做的事(明确拒绝) - ❌ **不**追求支持 GitHub + Gitea + GitLab 多平台。Gitea-only,避免抽象税 - ❌ **不**在路线 A 阶段做 Web UI / dashboard。命令行 + Gitea 评论已够 - ❌ **不**做"全自动决策合并 PR"。Claude 提 PR,人审核合并 - ❌ **不**移植上游所有 mode(review/agent 等),只做 tag mode ## 决策记录 非显然的设计选择记在 [04-decisions.md](04-decisions.md)。