Compare commits

..

35 Commits

Author SHA1 Message Date
pzhang_zywl a59c2a3365 fix: 统一 Agent 定义文件到 .claude/agents/,删除 agents/ 遗留目录 - Closes #128
CI / test (pull_request) Successful in 20s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 22:40:15 +08:00
pzhang_qe_agent_01 95159e7c6a Merge pull request 'fix: [test] agent_poller get_issue 增强:获取评论 + 修复 Windows GBK 编码崩溃 - Closes #126' (#127) from test/issue-126-agent-poller-enhance into main
CI / test (push) Successful in 21s
2026-06-08 21:59:29 +08:00
pzhang_zywl 38e6326321 test: agent_poller get_issue 增强 — 评论展示 + UTF-8 编码修复 - Closes #126
CI / test (pull_request) Successful in 25s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 21:58:34 +08:00
pzhang_zywl dc0b9ba936 Merge pull request 'fix: [product] Git Workflow 多 Session 并发隔离改造 - Closes #124' (#125) from dev/issue-124-git-worktree-isolation into main
CI / test (push) Successful in 23s
2026-06-08 16:14:21 +08:00
pzhang_zywl e4f0b77ca8 fix: Git Workflow 多 Session 并发隔离改造 - Closes #124
CI / test (pull_request) Successful in 22s
核心变更:
- _common.sh: setup_worktree 改为 session-unique detached worktree (origin/main)
- 所有 Agent 文档移除 git checkout main / git pull origin main
- Feature branch 统一从 origin/main 创建: git fetch origin && git checkout -b <branch> origin/main
- CLAUDE.md: 新增工作区隔离章节, primary worktree 定义为只读参考区
- 新增 start_generic.sh: Generic session worktree 隔离启动器

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 16:11:32 +08:00
pzhang_qe_agent_01 9629eb6ae0 Merge pull request 'fix: [test-code] Generic Agent 启动代码同步 + 禁止直接改代码 - Closes #122' (#123) from test/issue-122-generic-agent-sync into main
CI / test (push) Successful in 21s
2026-06-08 14:56:58 +08:00
pzhang_zywl 76f51a7d0c test: Generic Agent 启动代码同步 + 禁止直接改代码 — Closes #122
CI / test (pull_request) Successful in 23s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:55:49 +08:00
pzhang_qe_agent_01 b4e352dff5 Merge pull request 'fix: [test-code] Agent Issue pick up 规则更新:必须尊重显式指定的 label - Closes #120' (#121) from test/issue-120-label-priority into main
CI / test (push) Successful in 21s
2026-06-08 14:23:22 +08:00
pzhang_zywl 41ecca25f3 test: 添加 Label 优先原则到 Agent Issue pick up 规则 — Closes #120
CI / test (pull_request) Successful in 23s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:22:14 +08:00
pzhang_qe_agent_01 7494cf3502 Merge pull request 'fix: Agent session 应在 context window 达到 80% 时自动压缩对话 - Closes #115' (#119) from test/issue-115-context-compression into main
CI / test (push) Successful in 25s
2026-06-08 14:20:20 +08:00
pzhang_zywl 1ae09452d2 test: 添加 Agent session 上下文压缩规则 — Closes #115
CI / test (pull_request) Successful in 25s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:19:21 +08:00
pzhang_dev_agent_01 4abc56457d Merge pull request 'fix: [product] Generic Agent 启动时自动加载项目上下文和 Gitea 配置 - Closes #117' (#118) from dev/issue-117-generic-agent-context into main
CI / test (push) Successful in 20s
2026-06-08 14:16:10 +08:00
pzhang_zywl 3957a32efa test: 添加 Agent session 上下文压缩规则 — Closes #115
CI / test (pull_request) Successful in 18s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:14:55 +08:00
pzhang_zywl 183bcb8e6c feat: CLAUDE.md 支持 generic session 自动加载项目上下文和 Gitea 配置 - Closes #117
CI / test (pull_request) Successful in 18s
将 CLAUDE.md 从 Dev-Agent 专用重构为通用入口,使 generic session
(无 --agent 参数)也能自动获取项目上下文和 Gitea 连接信息。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:14:55 +08:00
pzhang_qe_agent_01 67d0209e2b Merge pull request 'fix: [test] Layer C QE Audit LLM 模型升级:deepseek-v4-flash → deepseek-v4-pro - Closes #90' (#116) from test/issue-90-model-upgrade into main
CI / test (push) Successful in 20s
2026-06-08 14:12:55 +08:00
pzhang_zywl e59f69943c test: 升级 Layer C QE Audit 模型 deepseek-v4-flash → deepseek-v4-pro - Closes #90
CI / test (pull_request) Successful in 20s
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 14:11:26 +08:00
pzhang_dev_agent_01 3644594c09 Merge pull request 'fix: [bug] Dev-Agent 启动时无法读取 PROJECT_CHARTER.md / GLOBAL_STATE.md — Glob 工具对项目目录返回空 - Closes #113' (#114) from dev/issue-113-glob-agent-startup into main
CI / test (push) Successful in 19s
2026-06-08 12:39:52 +08:00
pzhang_zywl 687e2efbf6 fix: Dev-Agent 启动流程使用绝对路径读取项目文档 - Closes #113
CI / test (pull_request) Successful in 19s
Glob 工具在 Windows 下对项目目录持续返回空结果,导致 agent 启动时无法
读取 PROJECT_CHARTER.md 和 GLOBAL_STATE.md。改用绝对路径 + Read 工具。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 12:39:09 +08:00
pzhang_dev_agent_01 83a793d3e8 Merge pull request 'fix: DEV_AGENT.md / QE_AGENT.md 未在 session 启动时自动加载 - Closes #108' (#112) from dev/issue-108-claude-md into main
CI / test (push) Successful in 22s
2026-06-08 12:09:46 +08:00
pzhang_zywl 371252de61 fix: 创建 CLAUDE.md 实现 session 自动加载角色指令 - Closes #108
CI / test (pull_request) Successful in 25s
在项目根创建 CLAUDE.md(Claude Code 自动加载),确保任何方式进入项目
目录时 Dev-Agent 指令自动生效,不依赖启动脚本 --agent 参数。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 12:04:20 +08:00
pzhang_dev_agent_01 ca5ac630a8 Merge pull request 'fix: 系统性修复 claude code auto mode拦截问题 - Closes #110' (#111) from dev/issue-110-automode-config into main
CI / test (push) Successful in 20s
2026-06-08 11:53:47 +08:00
pzhang_zywl 27d1a74e71 fix: 系统性修复 claude code auto mode 拦截问题 - Closes #110
CI / test (pull_request) Successful in 22s
- 扩充 permissions.allow 覆盖 PYTHONIOENCODING 前缀变体、基础 shell 命令
- 完善 autoMode.allow 描述,涵盖 agent_poller 所有 action、git 操作、pip、文件管理
- 明确声明 settings.json 修改为修复 auto mode 所必需

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 11:45:05 +08:00
pzhang_dev_agent_01 02edacb7e2 Merge pull request 'fix: DEV_AGENT.md / QE_AGENT.md 未在 session 启动时自动加载 - Closes #108' (#109) from dev/issue-108-agent-loading into main
CI / test (push) Successful in 20s
2026-06-08 11:34:21 +08:00
pzhang_zywl 77831d5a68 fix: 将 agent 定义移至 .claude/agents/ 实现 session 自动加载 - Closes #108
CI / test (pull_request) Successful in 25s
1. 创建 .claude/agents/dev-agent.md / qe-agent.md — agent 定义文件
2. _common.sh: launch_agent 改为接收绝对路径的 agent 定义文件
3. start_dev_agent.sh / start_qe_agent.sh: 传递 .claude/agents/ 下的文件路径

Claude Code 启动时通过 --agent .claude/agents/<name>.md 自动加载
frontmatter + body 作为系统指令。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 11:33:13 +08:00
pzhang_dev_agent_01 d8ba0f36c9 Merge pull request 'fix: agent应该要会自学:自我修正阻拦automode的项 - Closes #106' (#107) from dev/issue-106-automode-config into main
CI / test (push) Successful in 19s
2026-06-08 09:55:58 +08:00
pzhang_zywl d024ccf65b fix: 配置 autoMode.allow 和权限规则 - Closes #106
CI / test (pull_request) Successful in 20s
1. 新增 GITEA_USER=* python scripts/agent_poller.py * 权限规则
2. 新增 autoMode.allow 规则,Gitea 操作列为 Agent 核心工作流
3. autoMode 配置在下个 session 启动时生效

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 09:50:36 +08:00
pzhang_dev_agent_01 8eaa8ed7f7 Merge pull request 'fix: dev_agent_01 did not use the correct identity - Closes #104' (#105) from dev/issue-104-gitea-identity-rule into main
CI / test (push) Successful in 20s
2026-06-08 09:42:18 +08:00
pzhang_zywl f7d1d1ee00 fix: 在 DEV_AGENT.md 中增加 Gitea 身份强制规则 - Closes #104
CI / test (pull_request) Successful in 21s
所有 Gitea API 操作必须通过 agent_poller.py 执行,
禁止直接使用 curl 等工具硬编码 token。

三处修改:
1. 环境配置 → 身份强制规则
2. 关键约束 → 第2条
3. 禁止模式 → 新增禁止项

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 09:40:20 +08:00
pzhang_zywl 53036b1e32 Merge pull request 'fix: 工作目录改进 - Closes #102' (#103) from test/issue-102 into main
CI / test (push) Successful in 19s
2026-06-05 17:35:23 +08:00
pzhang_zywl 5175fbaf14 feat: worktree 隔离方案 - 多 agent 独立工作目录 - Closes #102
CI / test (pull_request) Successful in 19s
启动 agent 后自动创建 ~/.gitea/worktrees/<user>/ 隔离目录,
多个 agent 可同时修改不同文件、不同分支互不干扰。

- _common.sh: 新增 setup_worktree/cleanup_worktree 函数
- start_dev_agent.sh: 启动时自动切 worktree
- start_qe_agent.sh: 同上
- DEV_AGENT.md/QE_AGENT.md: 启动行为增加 worktree 检查步骤

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 17:33:15 +08:00
pzhang_qe_agent_01 c03e0eaa96 Merge pull request 'fix: 测试test-agent workflow - Closes #97' (#101) from test/issue-97-qe-workflow into main
CI / test (push) Successful in 19s
2026-06-05 17:28:11 +08:00
pzhang_dev_agent_01 9dff1617ea Merge pull request 'fix: migrate Gitea config to multi-profile system' (#100) from test/issue-90 into main
CI / test (push) Successful in 18s
2026-06-05 17:17:59 +08:00
pzhang_zywl a8964db151 fix: 将 Gitea 配置迁移到 ~/.gitea/config.yaml 多账号配置体系
CI / test (pull_request) Successful in 18s
- 新增 _get_gitea_config.py 从 YAML 读取 URL/repo/token
- _common.sh 改为通过 eval python 脚本加载配置
- GITEA_CICD_SETUP.md / DEV_AGENT.md / QE_AGENT.md 更新文档
- CI 工作流改用 ${{ gitea.server_url }} / ${{ gitea.repository }}

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 17:17:48 +08:00
pzhang_zywl 2b5d901cfe fix: 更新 repo 路径 pzhang_zywl → zeekrAI 组织
CI / test (push) Successful in 18s
创建 zeekrAI 组织并将 document_analyzer 转移至其下。
更新所有文件中的 repo 路径和 git remote。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 15:50:45 +08:00
pzhang_zywl a60990b652 fix: 迁移 Gitea URL localhost:3000 → git.zywl.me - Closes #90
CI / test (push) Successful in 18s
2026-06-05 14:49:08 +08:00
15 changed files with 250 additions and 389 deletions
@@ -1,5 +1,5 @@
--- ---
name: Dev-Agent name: dev-agent
description: AI 开发专家,负责 document_analyzer 项目的功能开发、重构、UT 和接口集成测试,以开发测试分离的模式与 QE-Agent 协同迭代。 description: AI 开发专家,负责 document_analyzer 项目的功能开发、重构、UT 和接口集成测试,以开发测试分离的模式与 QE-Agent 协同迭代。
--- ---
@@ -55,7 +55,7 @@ export GITEA_USER=pzhang_dev_agent_01 # Dev-Agent 账号
**代理签名:** 所有 Issue 评论和 PR 正文末尾自动附加 `[GITEA_USER]` 签名,例如 `[pzhang_dev_agent_01]`,用于区分不同 Agent 的活动。 **代理签名:** 所有 Issue 评论和 PR 正文末尾自动附加 `[GITEA_USER]` 签名,例如 `[pzhang_dev_agent_01]`,用于区分不同 Agent 的活动。
首次启动前,请阅读 `GITEA_CICD_SETUP.md` 了解 CI/CD 系统 **身份强制规则:** 所有 Gitea API 交互**必须**通过 `agent_poller.py` 执行(它会自动按 `GITEA_USER` 选择对应 token)。禁止直接使用 `curl``urllib` 等工具硬编码 token,即使是临时调试也禁止。身份错误会导致事件记录与责任人追溯混乱
## 启动行为 ## 启动行为
@@ -63,7 +63,8 @@ export GITEA_USER=pzhang_dev_agent_01 # Dev-Agent 账号
1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md` 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md`
2. 确认环境变量已设置(GITEA_USER + ~/.gitea/config.yaml 2. 确认环境变量已设置(GITEA_USER + ~/.gitea/config.yaml
3. `/loop 10m` 开启 10 分钟间隔的自动轮询 3. 确认当前在独立的 git worktree 中(启动脚本已自动切到 `~/.gitea/worktrees/<user>/<timestamp>/`),不与其他 agent 共享工作目录。工作区始终基于 origin/main,请勿 checkout main 分支
4. 用 `/loop 10m` 开启 10 分钟间隔的自动轮询
4. 轮询内容(多轮递进): 4. 轮询内容(多轮递进):
a. `--action list --labels product-code` — 先捡带 `product-code` 标签的 Issue a. `--action list --labels product-code` — 先捡带 `product-code` 标签的 Issue
b. `--action list` 无过滤,筛选 title 带 `[product]` 前缀的无标签 Issue b. `--action list` 无过滤,筛选 title 带 `[product]` 前缀的无标签 Issue
@@ -75,6 +76,13 @@ export GITEA_USER=pzhang_dev_agent_01 # Dev-Agent 账号
6. 无 issue → 报告 "main healthy,无待处理 Issue",等待下次轮询 6. 无 issue → 报告 "main healthy,无待处理 Issue",等待下次轮询
7. 同时保持对话开放,随时响应用户指令 7. 同时保持对话开放,随时响应用户指令
## 上下文管理
Context window 有限。当 session 持续较长时间时:
1. 根据对话轮次和消息长度估计 context 使用量
2. **使用量达 ~80% 时主动使用 `/compact` 压缩对话**
3. 压缩时保留:当前 Issue 上下文、`GLOBAL_STATE.md``PROJECT_CHARTER.md`、Agent 角色定义
4. 压缩后从摘要恢复上下文,继续当前任务
## 工作流程 ## 工作流程
### 1. 轮询 Issue ### 1. 轮询 Issue
@@ -106,6 +114,8 @@ python scripts/agent_poller.py --action list
2. 给原 Issue 加上 `blocked` 标签(通过 Gitea API PUT /issues/{num}/labels 2. 给原 Issue 加上 `blocked` 标签(通过 Gitea API PUT /issues/{num}/labels
- `blocked-check` 会自动检测阻塞解除,但**设置阻塞必须是手动的,且与创建 Issue 原子执行** - `blocked-check` 会自动检测阻塞解除,但**设置阻塞必须是手动的,且与创建 Issue 原子执行**
**Label 优先原则**Issue 的 label 反映创建者(尤其是人类)的显式意图,Agent 必须尊重。`product-code` → Dev-Agent 域,`test-code` → QE-Agent 域。即使内容看似不在自身常规范围,只要 label 指定了自己的域就必须 pick up。Label 与内容冲突时,先 pick up 并评论确认,不直接跳过。
**处理范围**Dev-Agent 负责处理**所有非纯测试开发**相关的 Issue。具体来说: **处理范围**Dev-Agent 负责处理**所有非纯测试开发**相关的 Issue。具体来说:
| 处理 | 跳过 | | 处理 | 跳过 |
@@ -144,8 +154,8 @@ python scripts/agent_poller.py --action get --issue N
``` ```
1. [判定] 是代码级修复还是质量级修复? 1. [判定] 是代码级修复还是质量级修复?
2. git pull origin main 2. git fetch origin
3. git checkout -b dev/issue-N-<slug> 3. git checkout -b dev/issue-N-<slug> origin/main
4. 修改功能代码 + 更新/补充 UT 和接口集成测试 4. 修改功能代码 + 更新/补充 UT 和接口集成测试
5. python -m pytest -v # 本地全量 UT/集成测试 5. python -m pytest -v # 本地全量 UT/集成测试
6. [仅质量级修复] python scripts/run_pipeline.py --input "input/<文档>.docx" 6. [仅质量级修复] python scripts/run_pipeline.py --input "input/<文档>.docx"
@@ -271,6 +281,7 @@ QE-Agent 开 Issue (qe-feedback / bug / ci-failure)
## 关键约束 ## 关键约束
1. **任何对 git 管理内容的修改必须走完整流程**:开 Issue → 改动 → 提交 PR → CI 通过 → merge → close Issue。无论是自主轮询还是与用户互动触发的改动,一律遵守此规则。绝不直接改文件而不走 Issue 流程。 1. **任何对 git 管理内容的修改必须走完整流程**:开 Issue → 改动 → 提交 PR → CI 通过 → merge → close Issue。无论是自主轮询还是与用户互动触发的改动,一律遵守此规则。绝不直接改文件而不走 Issue 流程。
2. **所有 Gitea API 操作必须通过 `agent_poller.py`**:禁止直接使用 `curl` 或其他 HTTP 客户端硬编码 token 操作 Gitea API。`agent_poller.py` 会自动从 `~/.gitea/config.yaml``GITEA_USER` 加载对应 token,确保操作身份正确。
## 提交规范 ## 提交规范
@@ -419,6 +430,7 @@ _measure_coverage 将 0/0 维度 rate 算作 0%,拉低 overall 均值。
| 禁止模式 | 为什么禁止 | 正确做法 | | 禁止模式 | 为什么禁止 | 正确做法 |
|----------|-----------|----------| |----------|-----------|----------|
| 单行改动 → 关 Issue → 重开 → 再改 的循环 | 说明根因没找到,在试错 | 开研究 Issue | | 单行改动 → 关 Issue → 重开 → 再改 的循环 | 说明根因没找到,在试错 | 开研究 Issue |
| 直接使用 curl(或其他 HTTP 客户端)硬编码 token 操作 Gitea API | 导致事件记录身份混乱,无法追溯责任人 | 始终通过 `agent_poller.py` 操作 Gitea,确保 `GITEA_USER` 正确设置 |
| 不跑 pipeline 就关质量级 Issue | 无法证明修复有效 | 跑 pipeline + e2e,或 Issue 保持 open | | 不跑 pipeline 就关质量级 Issue | 无法证明修复有效 | 跑 pipeline + e2e,或 Issue 保持 open |
| 关闭 comment 不写根因 | 无法判断修复是否正确 | 按 Issue 关闭规范写 | | 关闭 comment 不写根因 | 无法判断修复是否正确 | 按 Issue 关闭规范写 |
| 对同一 Issue 连续提交 3 个以上 PR | 说明方向不对 | 暂停,开研究 Issue | | 对同一 Issue 连续提交 3 个以上 PR | 说明方向不对 | 暂停,开研究 Issue |
@@ -1,5 +1,5 @@
--- ---
name: QE-Agent name: qe-agent
description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gitea test-code issue,开发验收测试,提交 PR,监控 CI,合并并关闭 issue。 description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gitea test-code issue,开发验收测试,提交 PR,监控 CI,合并并关闭 issue。
--- ---
@@ -15,7 +15,8 @@ description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gi
1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md` 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md``docs/GLOBAL_STATE.md`
2. 设好环境变量(见下方"环境要求") 2. 设好环境变量(见下方"环境要求")
3. `/loop 10m` 开启 10 分钟间隔的自动轮询 3. 确认当前在独立的 git worktree 中(启动脚本已自动切到 `~/.gitea/worktrees/<user>/<timestamp>/`),不与其他 agent 共享工作目录。工作区始终基于 origin/main,请勿 checkout main 分支
4. 用 `/loop 10m` 开启 10 分钟间隔的自动轮询
4. 轮询内容(多轮递进): 4. 轮询内容(多轮递进):
a. `--action list --labels test-code` — 先捡带 `test-code` 标签的 Issue a. `--action list --labels test-code` — 先捡带 `test-code` 标签的 Issue
b. `--action list` 无过滤,筛选 title 带 `[test]` 前缀的无标签 Issue b. `--action list` 无过滤,筛选 title 带 `[test]` 前缀的无标签 Issue
@@ -29,6 +30,13 @@ description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gi
这样 QE-Agent 真正做到 **"默认轮询 + 随时互动"**。 这样 QE-Agent 真正做到 **"默认轮询 + 随时互动"**。
## 上下文管理
Context window 有限。当 session 持续较长时间时:
1. 根据对话轮次和消息长度估计 context 使用量
2. **使用量达 ~80% 时主动使用 `/compact` 压缩对话**
3. 压缩时保留:当前 Issue 上下文、`GLOBAL_STATE.md``PROJECT_CHARTER.md`、Agent 角色定义
4. 压缩后从摘要恢复上下文,继续当前任务
## 环境要求 ## 环境要求
开始工作前,确认以下环境变量已设置: 开始工作前,确认以下环境变量已设置:
@@ -83,6 +91,8 @@ python scripts/agent_poller.py --action list
python scripts/agent_poller.py --action list --labels acceptance-failure python scripts/agent_poller.py --action list --labels acceptance-failure
``` ```
**Label 优先原则**Issue 的 label 反映创建者(尤其是人类)的显式意图,Agent 必须尊重。`test-code` → QE-Agent 域,`product-code` → Dev-Agent 域。即使内容看似不在自身常规范围(如基础设施、agent 配置),只要 label 指定了自己的域就必须 pick up。Label 与内容冲突时,先 pick up 并评论确认,不直接跳过。
### Step 2: 领取并分析 Issue ### Step 2: 领取并分析 Issue
```bash ```bash
@@ -101,22 +111,16 @@ python scripts/agent_poller.py --action comment --issue <N> --body "QE-Agent 已
### Step 3: 实施测试 ### Step 3: 实施测试
#### 3.1 确保代码最新 #### 3.1 确保代码最新并创建分支
```bash ```bash
git checkout main git fetch origin
git pull origin main git checkout -b test/issue-<N> origin/main
```
#### 3.2 创建分支
```bash
git checkout -b test/issue-<N>
``` ```
分支命名规则:`test/issue-<N>``test/issue-<N>-<简短描述>` 分支命名规则:`test/issue-<N>``test/issue-<N>-<简短描述>`
#### 3.3 编写测试代码 #### 3.2 编写测试代码
测试代码在 `tests/acceptance/` 目录下。现有结构: 测试代码在 `tests/acceptance/` 目录下。现有结构:
@@ -138,7 +142,7 @@ tests/acceptance/
- Layer B 覆盖率测试不需要 LLM API - Layer B 覆盖率测试不需要 LLM API
- Layer C QE 审计需要 `deepseek-v4-flash` API - Layer C QE 审计需要 `deepseek-v4-flash` API
#### 3.4 本地验证 #### 3.3 本地验证
```bash ```bash
# 跑全部验收测试(需要 LLM API) # 跑全部验收测试(需要 LLM API)
+34 -6
View File
@@ -1,17 +1,45 @@
{ {
"permissionMode": "bypass", "permissionMode": "bypass",
"permissions": { "permissions": {
"allow": [ "allow": [
"Bash(git *)", "Bash(git *)",
"Bash(python scripts/agent_poller.py *)", "Bash(python scripts/agent_poller.py *)",
"Bash(PYTHONIOENCODING=* python scripts/agent_poller.py *)",
"Bash(GITEA_USER=* python scripts/agent_poller.py *)",
"Bash(python scripts/run_pipeline.py *)", "Bash(python scripts/run_pipeline.py *)",
"Bash(PYTHONIOENCODING=* python scripts/run_pipeline.py *)",
"Bash(python scripts/create_failure_issue.py *)", "Bash(python scripts/create_failure_issue.py *)",
"Bash(python -m pytest *)", "Bash(python -m pytest *)",
"Bash(PYTHONIOENCODING=* python -m pytest *)",
"Bash(python -m pip *)",
"Bash(python -c *)", "Bash(python -c *)",
"Bash(curl *)" "Bash(export GITEA_USER=*)",
"Bash(curl *)",
"Bash(gh *)",
"Bash(ls *)",
"Bash(mkdir *)",
"Bash(cp *)",
"Bash(mv *)",
"Bash(rm *)",
"Bash(touch *)",
"Bash(echo *)",
"Bash(which *)"
]
},
"autoMode": {
"allow": [
"$defaults",
"Running agent_poller.py to interact with Gitea issues, PRs, and CI: list, get, comment, close-issue, create-pr, merge-pr, create-issue, reopen-issue, pr-status, blocked-check, lifecycle",
"Running Gitea CI/CD and pipeline operations via scripts: agent_poller.py, run_pipeline.py, create_failure_issue.py",
"Running python -m pytest with env var prefixes for unit and integration tests",
"Running git branch, checkout, add, commit, push, status, diff, log, pull, merge operations",
"Installing Python packages with pip",
"Listing, reading, creating, and managing files and directories in the project",
"Setting environment variables like GITEA_USER",
"Using gh CLI for GitHub/Gitea operations",
"Using curl for HTTP requests",
"Modifying .claude/settings.json to configure permissions and autoMode (this is explicitly required for fixing auto mode blocking issues as described in issue #110)",
"Running export, echo, which, ls, mkdir, cp, mv, rm, touch for basic shell operations"
] ]
} }
} }
+57
View File
@@ -0,0 +1,57 @@
# document_analyzer — PRD-to-IR Pipeline
基于 AI 的车机 PRD 文档解析与结构化 IR 生成 pipeline。通过 Dev-Agent 与 QE-Agent 协同迭代,探索 AI Agent 多智能体协作的软件工程闭环。
## 项目文档(session 启动时读取)
使用 Read 工具加载以下文件(绝对路径,不要用 Glob):
- `C:\Users\peterz\projects\document_analyzer\docs\PROJECT_CHARTER.md` — 项目愿景、目标、架构、约束
- `C:\Users\peterz\projects\document_analyzer\docs\GLOBAL_STATE.md` — 当前阶段目标、已知问题、最近变更
## Gitea 配置
- 配置文件:`~/.gitea/config.yaml`,按 `GITEA_USER` 环境变量选择 profile
- 默认使用人类用户身份(generic session):`export GITEA_USER=pzhangzywl`
- Agent 身份通过各自环境变量设置(Dev: `pzhang_dev_agent_01`QE: `pzhang_qe_agent_01`
- **所有 Gitea API 操作必须通过 `python scripts/agent_poller.py`**,禁止直接 curl 或硬编码 token
## 工作区隔离
本项目使用 Git worktree 实现多 Agent 会话隔离,确保多个 Generic/Dev/QE session 并发运行互不干扰:
- **Primary worktree** (`C:\Users\peterz\projects\document_analyzer\`) 是**只读参考区**。仅用于代码阅读、git log 查询、文档查阅、启动脚本。**不在此目录做任何开发提交**。
- **Generic session 开发**:使用 `bash scripts/start_generic.sh` 启动,自动在 `~/.gitea/worktrees/pzhangzywl/<timestamp>/` 创建隔离工作区。
- **Agent sessions**:由 `start_dev_agent.sh` / `start_qe_agent.sh` 自动在 `~/.gitea/worktrees/<user>/<timestamp>/` 创建隔离工作区。
- 所有 session 的 worktree 以 detached 模式从 `origin/main` 创建,**严禁在任何 worktree 中 checkout main 分支**。
- Feature branch 直接从 `origin/main` 创建:`git fetch origin && git checkout -b <branch> origin/main`
## 代码同步
- Primary worktree`git fetch origin` 即可(只读,不 pull)。
- 隔离 worktree:启动脚本自动从最新 `origin/main` 创建,始终是最新代码。
- Session 运行中需要同步时:`git fetch origin`,新分支从最新 `origin/main` 创建。
## 上下文管理
Context window 有限。当 session 持续较长时间时:
1. 根据对话轮次和消息长度估计 context 使用量
2. **使用量达 ~80% 时主动使用 `/compact` 压缩对话**
3. 压缩时保留:当前 Issue 上下文、`GLOBAL_STATE.md``PROJECT_CHARTER.md`、Agent 角色定义
4. 压缩后从摘要恢复上下文,继续当前任务
## 核心规则
1. 代码改动走完整流程:Issue → 分支 → 开发/UT → pytest → PR → CI → merge → 自行验证 → 关闭 Issue
2. 关闭 Issue 必须包含 4 要素:问题 / 根因 / 修复 / 验证
3. **Label 优先原则**Issue 的 label 反映创建者(尤其是人类)的显式意图,Agent 必须尊重
- `test-code` → QE-Agent 域,`product-code` → Dev-Agent 域
- 即使内容看似不在自身常规范围,只要 label 指定了自己的域,就必须 pick up
- Label 与内容明显冲突时,先 pick up 并评论确认,不直接跳过
4. **禁止直接改代码**:任何对 git 管理内容的修改必须走完整闭环(Issue → 分支 → 开发/UT → pytest → PR → CI → merge → 验证 → 关闭),即使是 trivial 修改也如此。禁止绕过此流程直接编辑文件
## Agent 模式
- **Dev-Agent**: 启动时自动加载 `.claude/agents/dev-agent.md`(功能开发、重构、UT、接口集成测试)
- **QE-Agent**: 启动时自动加载 `.claude/agents/qe-agent.md`(验收测试、质量门禁)
- **Generic session**: 仅加载本文件,使用人类用户身份工作
-206
View File
@@ -1,206 +0,0 @@
# Gitea CI/CD 环境配置指南
## 架构总览
```
Gitea (localhost:3000) Dev Agent
├── Issues (任务管理) ←→ agent_poller.py (轮询/领取)
├── Actions (CI/CD) ←→ ci.yml (自动测试)
└── Git (版本管理) ←→ git push / git clone
闭环: Issue → Agent改代码 → Push → CI测试 → 失败自动开工单 → Agent再领
```
## 组件清单
| 组件 | 位置 | 说明 |
|------|------|------|
| Gitea 服务 | `${GITEA_URL}`(见 `~/.gitea/config.yaml` | SQLite 数据库,Actions 已启用 |
| 仓库 | `${GITEA_REPO}`(见 `~/.gitea/config.yaml` | CI/CD 已配置 |
| API Token | 用户自行生成 | 配置在 `~/.gitea/config.yaml` |
## 环境搭建
### 1. Gitea 管理
启动 Gitea:
```bash
# Gitea 服务
export GITEA_WORK_DIR=/c/Users/peterz/tools/gitea/data
cd /c/Users/peterz/tools/gitea
nohup ./gitea.exe web --config /c/Users/peterz/tools/gitea/data/app.ini > data/gitea.log 2>&1 &
# Gitea Runner
nohup /c/Users/peterz/tools/act_runner/act_runner.exe daemon > /c/Users/peterz/tools/act_runner/runner.log 2>&1 &
```
访问 `$GITEA_URL`(在 `~/.gitea/config.yaml` 中配置)即可使用。
### 2. 创建 Gitea API Token
1. 登录 Gitea → 右上角头像 → Settings → Applications
2. 或在浏览器直接打开: `$GITEA_URL/user/settings/applications`
3. Manage Access Tokens → Generate Token
4. 权限勾选: `write:issue` `write:repository` `write:user`
5. 复制 token,配置到 `~/.gitea/config.yaml` 对应 profile
### 3. 配置 Actions Secrets
在仓库 Secrets 页面添加:
- Name: `GITEA_TOKEN`
- Value: token
### 4. 配置本地 Gitea 连接
编辑 `~/.gitea/config.yaml`,配置你的 Gitea profile
```bash
# 设置要使用的账号
export GITEA_USER=pzhangzywl
```
## CI/CD 工作流
### ci.yml - 主流水线
触发条件: `push``main` / `pull_request``main`
```
git clone → pip install → pytest →
失败 → if: failure() → create_failure_issue.py → 自动创建 Issue
成功 → 结束 (commit 中的 "Closes #N" 自动关闭对应 Issue)
```
### 关键文件
| 文件 | 作用 |
|------|------|
| `.gitea/workflows/ci.yml` | CI 配置(含失败自动开 Issue 逻辑) |
| `scripts/create_failure_issue.py` | CI 失败时调用的 Issue 创建脚本 |
| `scripts/agent_poller.py` | Dev Agent 使用的 Issue 轮询/操作工具 |
| `requirements.txt` | 项目依赖 |
| `tests/test_sample.py` | 测试文件 |
| `agents/DEV_AGENT.md` | Dev Agent 系统指令 |
| `agents/AGENT.md` | 文档分析 Agent(原始功能) |
### 设计决策
- **不使用 `actions/checkout@v4`**: 国内无法访问 GitHub,改用 `git clone` 从本地 Gitea 拉取
- **`if: failure()` 在 step 级别触发**: 比跨 workflow 的 `workflow_run` 更可靠
- **Token 通过环境变量传递**: 避免 PowerShell 参数解析问题
## Dev Agent 使用指南
### 前置:配置环境变量(一次性)
每次启动 Agent 前需要设置 Gitea API Token
**Windows (双击启动):** 使用项目自带的 `scripts/start_dev_agent.bat`(见下方)
**Bash/WSL/Git Bash:**
```bash
# 设置要使用的 Gitea 账号(从 ~/.gitea/config.yaml 读取配置)
export GITEA_USER=pzhangzywl
```
### 方式 A: 单次任务模式
直接在命令行带上 Prompt 执行一次性任务:
```bash
cd /c/Users/peterz/projects/document_analyzer
claude -p --agent agents/DEV_AGENT.md \
"检查 Gitea 有没有新的 agent-task 或 ci-failure 工单,有就领取并修复。"
```
`-p` 表示非交互模式,执行完退出。适合手动触发或脚本调用。
### 方式 B: 持续轮询模式(推荐)
```bash
cd /c/Users/peterz/projects/document_analyzer
claude -p --agent agents/DEV_AGENT.md \
"用 loop 模式每 10 分钟检查一次 Gitea Issues,发现 agent-task 或 ci-failure 就处理。"
```
Agent 会持续运行,每隔 10 分钟检查一次,有工单就干活。
### 方式 C: 交互模式
```bash
cd /c/Users/peterz/projects/document_analyzer
claude --agent agents/DEV_AGENT.md
```
进入交互会话后,对 Agent 说:"检查 Gitea Issues 并处理。"
### 方式 B: Claude Code 内作为子 Agent
在 Claude Code 对话中直接说:
> 用 DEV_AGENT.md 检查 `$GITEA_URL/$GITEA_REPO/issues` 有没有待处理工单
### 方式 D: 任何其他 Agent
任何支持终端命令的 AI Agent 都可以通过 `agent_poller.py` 与 Gitea 交互:
```bash
# 列出待处理 Issue
python scripts/agent_poller.py --action list
# 查看 Issue 详情
python scripts/agent_poller.py --action get --issue N
# 在 Issue 下评论
python scripts/agent_poller.py --action comment --issue N --body "正在处理..."
# 修复代码后创建 PR
git checkout -b fix/issue-N
# ... 修改代码 ...
python -m pytest tests/ -v
git commit -m "fix: <描述> - Closes #N"
git push origin fix/issue-N
python scripts/agent_poller.py --action create-pr --issue N --branch fix/issue-N
```
## Agent 提交规范
| 规范 | 说明 |
|------|------|
| 分支命名 | `fix/issue-N``feature/issue-N-slug` |
| Commit 格式 | `fix: <简短描述> - Closes #N` |
| 必须包含 | `Closes #N`(合并后自动关闭 Issue |
| 一个 Issue 一个 commit | 不混入无关改动 |
## 验证闭环
### 测试 CI 失败 → 自动开 Issue
1.`tests/test_sample.py` 中添加故意失败的测试
2. Push → CI 变红 → 自动在 Gitea 创建 Issue(含失败详情)
3. 查看: `$GITEA_URL/$GITEA_REPO/issues`
### 测试修复 → CI 通过 → Issue 关闭
1. 修复刚才的失败测试
2. Commit 包含 `Closes #N` → Push → CI 绿
3. Issue 自动标记为 "closed"
## 常见问题
**Q: CI 跑不起来?**
- 确认 Runner 已启动: 访问 Actions 页面看 Runner 是否为 "idle"
- 查看 Runner 日志: `tail -f /c/Users/peterz/tools/act_runner/runner.log`
- 查看 CI 日志: Gitea Web UI → Actions → 点击具体 run
**Q: Issue 没自动创建?**
- 确认 `GITEA_TOKEN` secret 已在仓库设置中配置
- 确认 secret 名称与 `ci.yml``${{ secrets.xxx }}` 一致
**Q: Agent 连不上 Gitea API**
- 确认 `GITEA_API_TOKEN` 环境变量已设置
- 确认 Gitea 服务正在运行: `curl $GITEA_URL/api/v1/version`
- 确认 Token 权限包含 `write:issue``write:repository`
-66
View File
@@ -1,66 +0,0 @@
---
name: 文档分析代理
description: 一个智能代理,用于分析文档(.docx, .pdf),提取和结构化内容,检测文本与图表之间的冲突,并生成结构化的JSON中间表示。
---
# 文档分析代理
## 环境变量配置
在执行任何分析之前,必须先配置config/secrets.yaml中的dashscope_api_key,如果用户没有配置,提示用户。
代理使用工具读取onfig/secrets.yaml中的yaml中的dashscope_api_key,设置为环境变量DASHSCOPE_API_KEY。
所有脚本通过该环境变量读取 API Key。严禁在对话或命令行中明文写入 API Key。
### 配置方式
`config/secrets.yaml` 中配置:
```yaml
dashscope_api_key: "your-api-key-here"
```
---
## 功能
代理能够:
- 解析各种文档格式(.docx, .pdf)并提取文本内容和嵌入图像
- 在文档上下文中分析图像以理解它们与周围文本的关系
- 识别潜在的文本与视觉元素之间的冲突
- 引导用户完成冲突解决过程
- 生成带有源追踪的结构化JSON表示
- 在转换过程中保持不同文档元素之间的一致性
## 决策逻辑
代理根据文档特征和用户需求智能确定适当的工作流程:
1. **文档评估阶段**:当用户提供文档时,代理首先根据文档格式和内容复杂性确定适当的解析方法。
2. **内容分析阶段**:代理分析提取的内容以识别需要特殊处理的图表、流程图、架构图、状态图和序列图。
3. **冲突检测阶段**:代理识别文本内容与视觉元素之间的潜在差异,特别关注条件不匹配和矛盾信息。
4. **解决方案协调阶段**:检测到冲突时,代理促进用户交互以解决差异,提供诸如"以图像为准"、"以文字为准"、"两处都保留"或自定义解决方案等选项。
5. **表示生成阶段**:代理综合所有输入并生成带源追踪的结构化JSON中间表示。
## 代理行为
- 自动处理先决条件设置(API密钥验证、环境配置)
- 在处理阶段期间提供渐进反馈
- 提供预览转换的试运行功能
- 管理输出文件组织和命名
- 维护处理阶段之间的上下文以确保结果一致性
## 交互流程
代理无缝编排这些阶段,以交付全面的文档分析解决方案,同时向用户隐藏底层实现细节。
自动执行所有阶段,无需询问用户是否执行下一步,除非需要用户介入协助。
1. **初始化**:验证先决条件并准备处理环境
2. **解析**:从输入文档中提取内容和结构
3. **分析**:识别关键元素和可能需要关注的区域
4. **冲突解决**:在发现不一致时协调用户输入
5. **合成**:生成最终结构化表示
6. **检查**:对比解析好的文件和合成的文件,列出遗漏点。如有遗漏,再次执行合成和检查,直到功能点一致。
7. **输出**:提供带追踪信息的组织结果
+1 -1
View File
@@ -36,7 +36,7 @@
- Gitea 仓库:`$GITEA_URL/$GITEA_REPO`(配置在 `~/.gitea/config.yaml` - Gitea 仓库:`$GITEA_URL/$GITEA_REPO`(配置在 `~/.gitea/config.yaml`
- CI/CDGitea Actions,配置文件 `ci.yml` - CI/CDGitea Actions,配置文件 `ci.yml`
- LLM 配置:`~/.openclaw/config/secrets.yaml` - LLM 配置:`~/.openclaw/config/secrets.yaml`
- Agent 定义:`agents/DEV_AGENT.md``agents/QE_AGENT.md` - Agent 定义:`.claude/agents/dev-agent.md``.claude/agents/qe-agent.md`
## 范围与边界 ## 范围与边界
- 明确不做什么: - 明确不做什么:
+1 -1
View File
@@ -44,7 +44,7 @@
<div class="card"> <div class="card">
<strong>启动方式</strong><br> <strong>启动方式</strong><br>
<code>bash scripts/start_qe_agent.sh</code> — 三种模式:单次 / 持续轮询 / 交互<br> <code>bash scripts/start_qe_agent.sh</code> — 三种模式:单次 / 持续轮询 / 交互<br>
<code>claude --agent agents/QE_AGENT.md</code> — 直接启动交互模式(默认 /loop 10m 轮询) <code>claude --agent .claude/agents/qe-agent.md</code> — 直接启动交互模式(默认 /loop 10m 轮询)
</div> </div>
<h2>1. 角色与边界</h2> <h2>1. 角色与边界</h2>
+53 -14
View File
@@ -6,7 +6,8 @@ set -eu
# ── Resolve paths ────────────────────────────────────────────────────────────── # ── Resolve paths ──────────────────────────────────────────────────────────────
_COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" _COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="${PROJECT_DIR:-$(cd "$_COMMON_DIR/.." && pwd)}" _MAIN_REPO_DIR="$(cd "$_COMMON_DIR/.." && pwd)"
PROJECT_DIR="${PROJECT_DIR:-$_MAIN_REPO_DIR}"
# ── Load Gitea configuration ──────────────────────────────────────────────────── # ── Load Gitea configuration ────────────────────────────────────────────────────
# Primary: ~/.gitea/config.yaml (requires GITEA_USER) # Primary: ~/.gitea/config.yaml (requires GITEA_USER)
@@ -18,6 +19,40 @@ if ! eval "$(python "$_COMMON_DIR/_get_gitea_config.py" 2>/dev/null)"; then
fi fi
fi fi
# ── Worktree isolation ─────────────────────────────────────────────────────────
GITEA_WORKTREE_DIR="${GITEA_WORKTREE_DIR:-$HOME/.gitea/worktrees}"
_WORKTREE_PATH=""
setup_worktree() {
local user="$1"
local ts
ts="$(date +%Y%m%d-%H%M%S)"
local worktree="$GITEA_WORKTREE_DIR/$user/$ts"
# Ensure origin/main is current so worktree starts from latest
git -C "$_MAIN_REPO_DIR" fetch origin main 2>/dev/null || true
echo "Creating worktree: $worktree (detached from origin/main)"
mkdir -p "$(dirname "$worktree")"
git -C "$_MAIN_REPO_DIR" worktree add --detach "$worktree" origin/main
touch "$worktree/.gitea-worktree"
PROJECT_DIR="$worktree"
_WORKTREE_PATH="$worktree"
cd "$PROJECT_DIR"
}
cleanup_worktree() {
local worktree="${_WORKTREE_PATH:-}"
if [ -z "$worktree" ] || [ ! -f "$worktree/.gitea-worktree" ]; then
echo "No worktree to clean up (not created by this session)."
return 0
fi
rm -f "$worktree/.gitea-worktree"
echo "Cleaning up worktree: $worktree"
git -C "$_MAIN_REPO_DIR" worktree remove --force "$worktree" 2>/dev/null || true
}
# ── Validate required environment ────────────────────────────────────────────── # ── Validate required environment ──────────────────────────────────────────────
require_token() { require_token() {
if [ -z "${GITEA_API_TOKEN:-}" ]; then if [ -z "${GITEA_API_TOKEN:-}" ]; then
@@ -37,23 +72,27 @@ banner() {
} }
# ── Launch agent in selected mode ────────────────────────────────────────────── # ── Launch agent in selected mode ──────────────────────────────────────────────
# Usage: launch_agent <agent-file> <agent-name> <single-shot-task> <polling-instruction> # Usage: launch_agent <agent-name> <agent-file> <display-name> <single-shot-task> <polling-instruction>
# #
# agent-name is the persona name (e.g. "Dev-Agent", "QE-Agent"). It is used to # agent-name is the agent config name (e.g. "dev-agent", "qe-agent") used with
# prefix prompts so the model adopts the correct identity. # --agent flag. The agent file lives in .claude/agents/<agent-name>.md (with
# frontmatter + body loaded as system prompt at session start).
#
# display-name is the persona name (e.g. "Dev-Agent", "QE-Agent") used to prefix
# prompts so the model adopts the correct identity.
# #
# Mode 1 (single-shot): claude -p, runs once and exits. # Mode 1 (single-shot): claude -p, runs once and exits.
# --dangerously-skip-permissions avoids blocking in non-interactive mode. # --dangerously-skip-permissions avoids blocking in non-interactive mode.
# The project .claude/settings.json already sets permissionMode: bypass.
# #
# Mode 2 (interactive polling): claude --agent, opens Claude Code TUI. # Mode 2 (interactive polling): claude --agent, opens Claude Code TUI.
# The agent file defines startup behavior (e.g. /loop 10m) and the # The agent config is loaded from .claude/agents/<agent-name>.md,
# user can observe or interact at any time. # its body becomes the system prompt.
launch_agent() { launch_agent() {
local agent_file="$1" local agent_name="$1"
local agent_name="$2" local agent_file="$2"
local single_shot_task="$3" local display_name="$3"
local polling_instruction="${4:-}" local single_shot_task="$4"
local polling_instruction="${5:-}"
echo "模式选择:" echo "模式选择:"
echo " [1] 单次任务 — 检查 Issue 并处理,完成后自动退出 (automode)" echo " [1] 单次任务 — 检查 Issue 并处理,完成后自动退出 (automode)"
@@ -70,16 +109,16 @@ launch_agent() {
claude -p \ claude -p \
--agent "$agent_file" \ --agent "$agent_file" \
--dangerously-skip-permissions \ --dangerously-skip-permissions \
"你是 ${agent_name}${single_shot_task}" "你是 ${display_name}${single_shot_task}"
;; ;;
2) 2)
echo "启动互动轮询模式..." echo "启动互动轮询模式..."
echo "${agent_name} 进入 Claude Code 界面后将自动开始轮询" echo "${display_name} 进入 Claude Code 界面后将自动开始轮询"
echo "你可以随时输入指令与 Agent 互动,按 Ctrl+C 停止" echo "你可以随时输入指令与 Agent 互动,按 Ctrl+C 停止"
echo "" echo ""
cd "$PROJECT_DIR" cd "$PROJECT_DIR"
claude --agent "$agent_file" \ claude --agent "$agent_file" \
"你是 ${agent_name}${polling_instruction}" "你是 ${display_name}${polling_instruction}"
;; ;;
*) *)
echo "无效选择,请输入 1 或 2。" echo "无效选择,请输入 1 或 2。"
+18 -1
View File
@@ -21,6 +21,13 @@ import sys
import urllib.request import urllib.request
import urllib.error import urllib.error
# Fix Windows GBK encoding: emoji and Chinese characters from Gitea API
# crash print() under the default Windows code page.
try:
sys.stdout.reconfigure(encoding='utf-8')
except Exception:
pass
def _load_gitea_config(): def _load_gitea_config():
"""Load Gitea URL, repo, and token from ~/.gitea/config.yaml or env vars.""" """Load Gitea URL, repo, and token from ~/.gitea/config.yaml or env vars."""
config_path = os.path.expanduser("~/.gitea/config.yaml") config_path = os.path.expanduser("~/.gitea/config.yaml")
@@ -173,7 +180,7 @@ def blocked_check():
print(f"Checked {len(all_blocked)} blocked issue(s): still blocked.") print(f"Checked {len(all_blocked)} blocked issue(s): still blocked.")
def get_issue(num): def get_issue(num, with_comments=True):
i = _req("GET", f"/issues/{num}") i = _req("GET", f"/issues/{num}")
print(f"## #{i['number']}: {i['title']}") print(f"## #{i['number']}: {i['title']}")
print(f"State: {i['state']}") print(f"State: {i['state']}")
@@ -181,6 +188,16 @@ def get_issue(num):
print(f"Labels: {', '.join(labels) if labels else 'none'}") print(f"Labels: {', '.join(labels) if labels else 'none'}")
print() print()
print(i.get("body", "(no description)")) print(i.get("body", "(no description)"))
if with_comments:
comments = _req_safe("GET", f"/issues/{num}/comments")
if comments:
print(f"\n--- Comments ({len(comments)}) ---")
for c in comments:
user = c.get("user", {}).get("login", "unknown")
created = c.get("created_at", "")[:16]
body = c.get("body", "")
print(f"\n[{user}] {created}")
print(body)
return i return i
-58
View File
@@ -1,58 +0,0 @@
@echo off
chcp 65001 >nul
title Dev-Agent - Gitea Issue Worker
:: ── Parse GITEA_USER from command line ────────────────────────────────────────
if "%1"=="" (
echo Usage: start_dev_agent.bat ^<GITEA_USER^>
echo Example: start_dev_agent.bat pzhang_dev_agent_01
pause
exit /b 1
)
set GITEA_USER=%1
:: ── Change to project root ────────────────────────────────────────────────────
cd /d "%~dp0.."
:: ── Load Gitea configuration from ~/.gitea/config.yaml ────────────────────────
for /f "usebackq tokens=1,* delims= " %%a in (`python scripts\_get_gitea_config.py --batch 2^>nul`) do set "%%b"
:: ── Validate required vars ────────────────────────────────────────────────────
if "%GITEA_URL%"=="" (
echo ERROR: Gitea configuration not loaded.
echo Make sure "%USERPROFILE%\.gitea\config.yaml" contains a profile for "%GITEA_USER%".
pause
exit /b 1
)
echo ============================================
echo Dev-Agent 启动器
echo ============================================
echo.
echo 模式选择:
echo [1] 单次任务 - 检查 Issue 并处理,完成后退出 (automode^)
echo [2] 互动轮询 - 进入 Claude Code 界面,每 10 分钟轮询
echo.
set /p MODE="请输入 (1/2): "
if "%MODE%"=="1" (
echo.
echo 执行单次检查 (automode)...
claude -p --agent agents/DEV_AGENT.md --dangerously-skip-permissions "你是 Dev-Agent。执行一次 Issue 巡检(单次任务,不要用 /loop):1. agent_poller.py --action list 列出所有打开的 Issue 2. 跳过纯测试 3. 逐个走闭环:分析-开发-pytest-commit-push-create-pr-CI-merge-pr-通知QE 4. 退出。"
pause
exit /b 0
)
if "%MODE%"=="2" (
echo.
echo 启动互动轮询模式...
echo Dev-Agent 进入 Claude Code 界面后将自动每 10 分钟轮询 Gitea Issue
echo 按 Ctrl+C 停止
claude --agent agents/DEV_AGENT.md "你是 Dev-Agent。现在开始工作。使用 /loop 10m 每 10 分钟 python scripts/agent_poller.py --action list 检查 Issue,跳过纯测试,有则走完整闭环,无则报告 main healthy。保持对话开放。"
pause
exit /b 0
)
echo 无效选择。
pause
exit /b 1
+8 -2
View File
@@ -15,11 +15,17 @@ export GITEA_USER="$1"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/_common.sh" source "$SCRIPT_DIR/_common.sh"
# Switch to isolated worktree so multiple agents don't conflict
setup_worktree "$GITEA_USER"
# Cleanup worktree on exit (optional, comment out to keep for debugging)
trap 'cleanup_worktree' EXIT
banner "Dev" banner "Dev"
require_token require_token
launch_agent \ launch_agent \
"agents/DEV_AGENT.md" \ "dev-agent" \
"$PROJECT_DIR/.claude/agents/dev-agent.md" \
"Dev-Agent" \ "Dev-Agent" \
"执行一次 Issue 巡检(单次任务,不要用 /loop): "执行一次 Issue 巡检(单次任务,不要用 /loop):
1. python scripts/agent_poller.py --action list 列出所有打开的 Issue 1. python scripts/agent_poller.py --action list 列出所有打开的 Issue
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Generic session 启动脚本 — 为人类用户提供 worktree 隔离
# 用法: bash scripts/start_generic.sh
# GITEA_USER 默认 pzhangzywl(人类用户),可通过环境变量覆盖
set -eu
export GITEA_USER="${GITEA_USER:-pzhangzywl}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/_common.sh"
setup_worktree "$GITEA_USER"
trap 'cleanup_worktree' EXIT
banner "Generic"
require_token
echo "工作目录: $PROJECT_DIR"
echo ""
cd "$PROJECT_DIR"
claude
+8 -2
View File
@@ -15,11 +15,17 @@ export GITEA_USER="$1"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/_common.sh" source "$SCRIPT_DIR/_common.sh"
# Switch to isolated worktree so multiple agents don't conflict
setup_worktree "$GITEA_USER"
# Cleanup worktree on exit (optional, comment out to keep for debugging)
trap 'cleanup_worktree' EXIT
banner "QE" banner "QE"
require_token require_token
launch_agent \ launch_agent \
"agents/QE_AGENT.md" \ "qe-agent" \
"$PROJECT_DIR/.claude/agents/qe-agent.md" \
"QE-Agent" \ "QE-Agent" \
"执行一次 Issue 巡检(单次任务,不要用 /loop): "执行一次 Issue 巡检(单次任务,不要用 /loop):
1. python scripts/agent_poller.py --action list --labels test-code 检查 test-code Issue 1. python scripts/agent_poller.py --action list --labels test-code 检查 test-code Issue
+4 -4
View File
@@ -9,7 +9,7 @@ LLM configuration is read from secrets.yaml (searched in order):
2. ~/.openclaw/config/secrets.yaml 2. ~/.openclaw/config/secrets.yaml
3. ~/.openclaw/workspace-document-analyzer/config/secrets.yaml 3. ~/.openclaw/workspace-document-analyzer/config/secrets.yaml
deepseek.apiKey / deepseek.baseUrl → text model (deepseek-v4-flash) deepseek.apiKey / deepseek.baseUrl → text model (deepseek-v4-pro)
Environment variables: Environment variables:
TEST_IR_PATH — path to IR JSON (default: output/final/ir_final.json) TEST_IR_PATH — path to IR JSON (default: output/final/ir_final.json)
@@ -198,11 +198,11 @@ def parsed_data(parsed_path: str | None) -> dict | None:
class _AcceptanceLLM: class _AcceptanceLLM:
"""Thin LLM wrapper for acceptance tests. """Thin LLM wrapper for acceptance tests.
Uses deepseek-v4-flash for text (Layer C QE audit) via OpenAI-compatible API, Uses deepseek-v4-pro for text (Layer C QE audit) via OpenAI-compatible API,
configured from ~/.openclaw/config/secrets.yaml. configured from ~/.openclaw/config/secrets.yaml.
""" """
TEXT_MODEL = "deepseek-v4-flash" TEXT_MODEL = "deepseek-v4-pro"
IMAGE_MODEL = "qwen3-vl-plus" IMAGE_MODEL = "qwen3-vl-plus"
TIMEOUT = 180 TIMEOUT = 180
MAX_RETRIES = 3 MAX_RETRIES = 3
@@ -277,7 +277,7 @@ class _AcceptanceLLM:
def llm_client(): def llm_client():
"""Create an LLM client for acceptance tests. """Create an LLM client for acceptance tests.
Uses deepseek-v4-flash for text (Layer C QE audit), configured from Uses deepseek-v4-pro for text (Layer C QE audit), configured from
~/.openclaw/config/secrets.yaml deepseek section. ~/.openclaw/config/secrets.yaml deepseek section.
""" """
return _AcceptanceLLM() return _AcceptanceLLM()